Merge pull request #1 from esphome/dev

merge dev into fork
This commit is contained in:
Siemon Geeroms 2023-12-07 11:59:56 +01:00 committed by GitHub
commit f7fbc2d44f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 1795 additions and 639 deletions

View file

@ -37,6 +37,7 @@
"!secret scalar", "!secret scalar",
"!lambda scalar", "!lambda scalar",
"!extend scalar", "!extend scalar",
"!remove scalar",
"!include_dir_named scalar", "!include_dir_named scalar",
"!include_dir_list scalar", "!include_dir_list scalar",
"!include_dir_merge_list scalar", "!include_dir_merge_list scalar",

View file

@ -17,7 +17,7 @@ runs:
steps: steps:
- name: Set up Python ${{ inputs.python-version }} - name: Set up Python ${{ inputs.python-version }}
id: python id: python
uses: actions/setup-python@v4.7.0 uses: actions/setup-python@v5.0.0
with: with:
python-version: ${{ inputs.python-version }} python-version: ${{ inputs.python-version }}
- name: Restore Python virtual environment - name: Restore Python virtual environment

View file

@ -42,7 +42,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4.7.1 uses: actions/setup-python@v5.0.0
with: with:
python-version: "3.9" python-version: "3.9"
- name: Set up Docker Buildx - name: Set up Docker Buildx

View file

@ -40,7 +40,7 @@ jobs:
run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python id: python
uses: actions/setup-python@v4.7.1 uses: actions/setup-python@v5.0.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore Python virtual environment - name: Restore Python virtual environment

View file

@ -45,7 +45,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4.7.1 uses: actions/setup-python@v5.0.0
with: with:
python-version: "3.x" python-version: "3.x"
- name: Set up python environment - name: Set up python environment
@ -80,7 +80,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4.1.1 - uses: actions/checkout@v4.1.1
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4.7.1 uses: actions/setup-python@v5.0.0
with: with:
python-version: "3.9" python-version: "3.9"

View file

@ -22,7 +22,7 @@ jobs:
path: lib/home-assistant path: lib/home-assistant
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v4.7.1 uses: actions/setup-python@v5.0.0
with: with:
python-version: 3.11 python-version: 3.11

View file

@ -389,7 +389,8 @@ def command_config(args, config):
output = re.sub( output = re.sub(
r"(password|key|psk|ssid)\: (.+)", r"\1: \\033[5m\2\\033[6m", output r"(password|key|psk|ssid)\: (.+)", r"\1: \\033[5m\2\\033[6m", output
) )
safe_print(output) if not CORE.quiet:
safe_print(output)
_LOGGER.info("Configuration is valid!") _LOGGER.info("Configuration is valid!")
return 0 return 0

View file

@ -8,50 +8,37 @@ namespace esphome {
namespace a01nyub { namespace a01nyub {
static const char *const TAG = "a01nyub.sensor"; static const char *const TAG = "a01nyub.sensor";
static const uint8_t MAX_DATA_LENGTH_BYTES = 4;
void A01nyubComponent::loop() { void A01nyubComponent::loop() {
uint8_t data; uint8_t data;
while (this->available() > 0) { while (this->available() > 0) {
if (this->read_byte(&data)) { this->read_byte(&data);
buffer_.push_back(data); if (this->buffer_.empty() && (data != 0xff))
continue;
buffer_.push_back(data);
if (this->buffer_.size() == 4)
this->check_buffer_(); this->check_buffer_();
}
} }
} }
void A01nyubComponent::check_buffer_() { void A01nyubComponent::check_buffer_() {
if (this->buffer_.size() >= MAX_DATA_LENGTH_BYTES) { uint8_t checksum = this->buffer_[0] + this->buffer_[1] + this->buffer_[2];
size_t i; if (this->buffer_[3] == checksum) {
for (i = 0; i < this->buffer_.size(); i++) { float distance = (this->buffer_[1] << 8) + this->buffer_[2];
// Look for the first packet if (distance > 280) {
if (this->buffer_[i] == 0xFF) { float meters = distance / 1000.0;
if (i + 1 + 3 < this->buffer_.size()) { // Packet is not complete ESP_LOGV(TAG, "Distance from sensor: %f mm, %f m", distance, meters);
return; // Wait for completion this->publish_state(meters);
} } else {
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
uint8_t checksum = (this->buffer_[i] + this->buffer_[i + 1] + this->buffer_[i + 2]) & 0xFF;
if (this->buffer_[i + 3] == checksum) {
float distance = (this->buffer_[i + 1] << 8) + this->buffer_[i + 2];
if (distance > 280) {
float meters = distance / 1000.0;
ESP_LOGV(TAG, "Distance from sensor: %f mm, %f m", distance, meters);
this->publish_state(meters);
} else {
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
}
}
break;
}
} }
this->buffer_.clear(); } else {
ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]);
} }
this->buffer_.clear();
} }
void A01nyubComponent::dump_config() { void A01nyubComponent::dump_config() { LOG_SENSOR("", "A01nyub Sensor", this); }
ESP_LOGCONFIG(TAG, "A01nyub Sensor:");
LOG_SENSOR(" ", "Distance", this);
}
} // namespace a01nyub } // namespace a01nyub
} // namespace esphome } // namespace esphome

View file

@ -1,7 +1,7 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome import pins from esphome import pins
from esphome.const import CONF_ANALOG, CONF_INPUT from esphome.const import CONF_ANALOG, CONF_INPUT, CONF_NUMBER
from esphome.core import CORE from esphome.core import CORE
from esphome.components.esp32 import get_esp32_variant from esphome.components.esp32 import get_esp32_variant
@ -152,7 +152,8 @@ def validate_adc_pin(value):
return cv.only_on_rp2040("TEMPERATURE") return cv.only_on_rp2040("TEMPERATURE")
if CORE.is_esp32: if CORE.is_esp32:
value = pins.internal_gpio_input_pin_number(value) conf = pins.internal_gpio_input_pin_schema(value)
value = conf[CONF_NUMBER]
variant = get_esp32_variant() variant = get_esp32_variant()
if ( if (
variant not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL variant not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL
@ -166,24 +167,23 @@ def validate_adc_pin(value):
): ):
raise cv.Invalid(f"{variant} doesn't support ADC on this pin") raise cv.Invalid(f"{variant} doesn't support ADC on this pin")
return pins.internal_gpio_input_pin_schema(value) return conf
if CORE.is_esp8266: if CORE.is_esp8266:
value = pins.internal_gpio_pin_number({CONF_ANALOG: True, CONF_INPUT: True})( conf = pins.gpio_pin_schema(
value
)
if value != 17: # A0
raise cv.Invalid("ESP8266: Only pin A0 (GPIO17) supports ADC")
return pins.gpio_pin_schema(
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True {CONF_ANALOG: True, CONF_INPUT: True}, internal=True
)(value) )(value)
if conf[CONF_NUMBER] != 17: # A0
raise cv.Invalid("ESP8266: Only pin A0 (GPIO17) supports ADC")
return conf
if CORE.is_rp2040: if CORE.is_rp2040:
value = pins.internal_gpio_input_pin_number(value) conf = pins.internal_gpio_input_pin_schema(value)
if value not in (26, 27, 28, 29): number = conf[CONF_NUMBER]
if number not in (26, 27, 28, 29):
raise cv.Invalid("RP2040: Only pins 26, 27, 28 and 29 support ADC") raise cv.Invalid("RP2040: Only pins 26, 27, 28 and 29 support ADC")
return pins.internal_gpio_input_pin_schema(value) return conf
if CORE.is_libretiny: if CORE.is_libretiny:
return pins.gpio_pin_schema( return pins.gpio_pin_schema(

View file

@ -3,15 +3,13 @@ from typing import Any
from esphome.const import ( from esphome.const import (
CONF_ID, CONF_ID,
CONF_INPUT,
CONF_INVERTED, CONF_INVERTED,
CONF_MODE, CONF_MODE,
CONF_NUMBER, CONF_NUMBER,
CONF_OPEN_DRAIN, CONF_OPEN_DRAIN,
CONF_OUTPUT, CONF_OUTPUT,
CONF_PULLDOWN,
CONF_PULLUP,
CONF_IGNORE_STRAPPING_WARNING, CONF_IGNORE_STRAPPING_WARNING,
PLATFORM_ESP32,
) )
from esphome import pins from esphome import pins
from esphome.core import CORE from esphome.core import CORE
@ -33,7 +31,6 @@ from .const import (
esp32_ns, esp32_ns,
) )
from .gpio_esp32 import esp32_validate_gpio_pin, esp32_validate_supports from .gpio_esp32 import esp32_validate_gpio_pin, esp32_validate_supports
from .gpio_esp32_s2 import esp32_s2_validate_gpio_pin, esp32_s2_validate_supports from .gpio_esp32_s2 import esp32_s2_validate_gpio_pin, esp32_s2_validate_supports
from .gpio_esp32_c3 import esp32_c3_validate_gpio_pin, esp32_c3_validate_supports from .gpio_esp32_c3 import esp32_c3_validate_gpio_pin, esp32_c3_validate_supports
@ -42,7 +39,6 @@ from .gpio_esp32_c2 import esp32_c2_validate_gpio_pin, esp32_c2_validate_support
from .gpio_esp32_c6 import esp32_c6_validate_gpio_pin, esp32_c6_validate_supports from .gpio_esp32_c6 import esp32_c6_validate_gpio_pin, esp32_c6_validate_supports
from .gpio_esp32_h2 import esp32_h2_validate_gpio_pin, esp32_h2_validate_supports from .gpio_esp32_h2 import esp32_h2_validate_gpio_pin, esp32_h2_validate_supports
ESP32InternalGPIOPin = esp32_ns.class_("ESP32InternalGPIOPin", cg.InternalGPIOPin) ESP32InternalGPIOPin = esp32_ns.class_("ESP32InternalGPIOPin", cg.InternalGPIOPin)
@ -161,33 +157,22 @@ DRIVE_STRENGTHS = {
} }
gpio_num_t = cg.global_ns.enum("gpio_num_t") gpio_num_t = cg.global_ns.enum("gpio_num_t")
CONF_DRIVE_STRENGTH = "drive_strength" CONF_DRIVE_STRENGTH = "drive_strength"
ESP32_PIN_SCHEMA = cv.All( ESP32_PIN_SCHEMA = cv.All(
{ pins.gpio_base_schema(ESP32InternalGPIOPin, validate_gpio_pin).extend(
cv.GenerateID(): cv.declare_id(ESP32InternalGPIOPin), {
cv.Required(CONF_NUMBER): validate_gpio_pin, cv.Optional(CONF_IGNORE_STRAPPING_WARNING, default=False): cv.boolean,
cv.Optional(CONF_MODE, default={}): cv.Schema( cv.Optional(CONF_DRIVE_STRENGTH, default="20mA"): cv.All(
{ cv.float_with_unit("current", "mA", optional_unit=True),
cv.Optional(CONF_INPUT, default=False): cv.boolean, cv.enum(DRIVE_STRENGTHS),
cv.Optional(CONF_OUTPUT, default=False): cv.boolean, ),
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean, }
cv.Optional(CONF_PULLUP, default=False): cv.boolean, ),
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
}
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
cv.Optional(CONF_IGNORE_STRAPPING_WARNING, default=False): cv.boolean,
cv.Optional(CONF_DRIVE_STRENGTH, default="20mA"): cv.All(
cv.float_with_unit("current", "mA", optional_unit=True),
cv.enum(DRIVE_STRENGTHS),
),
},
validate_supports, validate_supports,
) )
@pins.PIN_SCHEMA_REGISTRY.register("esp32", ESP32_PIN_SCHEMA) @pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_ESP32, ESP32_PIN_SCHEMA)
async def esp32_pin_to_code(config): async def esp32_pin_to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
num = config[CONF_NUMBER] num = config[CONF_NUMBER]

View file

@ -12,6 +12,7 @@ from esphome.const import (
CONF_OUTPUT, CONF_OUTPUT,
CONF_PULLDOWN, CONF_PULLDOWN,
CONF_PULLUP, CONF_PULLUP,
PLATFORM_ESP8266,
) )
from esphome import pins from esphome import pins
from esphome.core import CORE, coroutine_with_priority from esphome.core import CORE, coroutine_with_priority
@ -21,10 +22,8 @@ import esphome.codegen as cg
from . import boards from . import boards
from .const import KEY_BOARD, KEY_ESP8266, KEY_PIN_INITIAL_STATES, esp8266_ns from .const import KEY_BOARD, KEY_ESP8266, KEY_PIN_INITIAL_STATES, esp8266_ns
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ESP8266GPIOPin = esp8266_ns.class_("ESP8266GPIOPin", cg.InternalGPIOPin) ESP8266GPIOPin = esp8266_ns.class_("ESP8266GPIOPin", cg.InternalGPIOPin)
@ -124,6 +123,8 @@ def validate_supports(value):
(True, False, False, False, False), (True, False, False, False, False),
# OUTPUT # OUTPUT
(False, True, False, False, False), (False, True, False, False, False),
# INPUT and OUTPUT, e.g. for i2c
(True, True, False, False, False),
# INPUT_PULLUP # INPUT_PULLUP
(True, False, False, True, False), (True, False, False, True, False),
# INPUT_PULLDOWN_16 # INPUT_PULLDOWN_16
@ -142,21 +143,11 @@ def validate_supports(value):
ESP8266_PIN_SCHEMA = cv.All( ESP8266_PIN_SCHEMA = cv.All(
{ pins.gpio_base_schema(
cv.GenerateID(): cv.declare_id(ESP8266GPIOPin), ESP8266GPIOPin,
cv.Required(CONF_NUMBER): validate_gpio_pin, validate_gpio_pin,
cv.Optional(CONF_MODE, default={}): cv.Schema( modes=pins.GPIO_STANDARD_MODES + (CONF_ANALOG,),
{ ),
cv.Optional(CONF_ANALOG, default=False): cv.boolean,
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
}
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
},
validate_supports, validate_supports,
) )
@ -167,7 +158,7 @@ class PinInitialState:
level: int = 255 level: int = 255
@pins.PIN_SCHEMA_REGISTRY.register("esp8266", ESP8266_PIN_SCHEMA) @pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_ESP8266, ESP8266_PIN_SCHEMA)
async def esp8266_pin_to_code(config): async def esp8266_pin_to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
num = config[CONF_NUMBER] num = config[CONF_NUMBER]

View file

@ -17,10 +17,8 @@ import esphome.codegen as cg
from .const import host_ns from .const import host_ns
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
HostGPIOPin = host_ns.class_("HostGPIOPin", cg.InternalGPIOPin) HostGPIOPin = host_ns.class_("HostGPIOPin", cg.InternalGPIOPin)
@ -45,21 +43,10 @@ def validate_gpio_pin(value):
return _translate_pin(value) return _translate_pin(value)
HOST_PIN_SCHEMA = cv.All( HOST_PIN_SCHEMA = pins.gpio_base_schema(
{ HostGPIOPin,
cv.GenerateID(): cv.declare_id(HostGPIOPin), validate_gpio_pin,
cv.Required(CONF_NUMBER): validate_gpio_pin, modes=[CONF_INPUT, CONF_OUTPUT, CONF_OPEN_DRAIN, CONF_PULLUP, CONF_PULLDOWN],
cv.Optional(CONF_MODE, default={}): cv.Schema(
{
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
}
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
},
) )

View file

@ -39,9 +39,8 @@ def _bus_declare_type(value):
raise NotImplementedError raise NotImplementedError
pin_with_input_and_output_support = cv.All( pin_with_input_and_output_support = pins.internal_gpio_pin_number(
pins.internal_gpio_pin_number({CONF_INPUT: True}), {CONF_OUTPUT: True, CONF_INPUT: True}
pins.internal_gpio_pin_number({CONF_OUTPUT: True}),
) )

View file

@ -255,12 +255,11 @@ class LD2420Component : public Component, public uart::UARTDevice {
uint16_t gate_energy_[LD2420_TOTAL_GATES]; uint16_t gate_energy_[LD2420_TOTAL_GATES];
CmdReplyT cmd_reply_; CmdReplyT cmd_reply_;
uint32_t timeout_;
uint32_t max_distance_gate_; uint32_t max_distance_gate_;
uint32_t min_distance_gate_; uint32_t min_distance_gate_;
uint16_t system_mode_{CMD_SYSTEM_MODE_ENERGY}; uint16_t system_mode_{CMD_SYSTEM_MODE_ENERGY};
bool cmd_active_{false}; bool cmd_active_{false};
char ld2420_firmware_ver_[8]; char ld2420_firmware_ver_[8]{"v0.0.0"};
bool presence_{false}; bool presence_{false};
bool calibration_{false}; bool calibration_{false};
uint16_t distance_{0}; uint16_t distance_{0};

View file

@ -186,25 +186,11 @@ def validate_gpio_usage(value):
return value return value
BASE_PIN_SCHEMA = cv.Schema( BASE_PIN_SCHEMA = pins.gpio_base_schema(
{ ArduinoInternalGPIOPin,
cv.GenerateID(): cv.declare_id(ArduinoInternalGPIOPin), validate_gpio_pin,
cv.Required(CONF_NUMBER): validate_gpio_pin, modes=pins.GPIO_STANDARD_MODES + (CONF_ANALOG,),
cv.Optional(CONF_MODE, default={}): cv.Schema( ).add_extra(validate_gpio_usage)
{
cv.Optional(CONF_ANALOG, default=False): cv.boolean,
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
}
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
},
)
BASE_PIN_SCHEMA.add_extra(validate_gpio_usage)
async def component_pin_to_code(config): async def component_pin_to_code(config):

View file

@ -74,20 +74,14 @@ def validate_mode(value):
CONF_MAX6956 = "max6956" CONF_MAX6956 = "max6956"
MAX6956_PIN_SCHEMA = cv.All( MAX6956_PIN_SCHEMA = pins.gpio_base_schema(
MAX6956GPIOPin,
cv.int_range(min=4, max=31),
modes=[CONF_INPUT, CONF_PULLUP, CONF_OUTPUT],
mode_validator=validate_mode,
).extend(
{ {
cv.GenerateID(): cv.declare_id(MAX6956GPIOPin),
cv.Required(CONF_MAX6956): cv.use_id(MAX6956), cv.Required(CONF_MAX6956): cv.use_id(MAX6956),
cv.Required(CONF_NUMBER): cv.int_range(min=4, max=31),
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
},
validate_mode,
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
} }
) )

View file

@ -45,19 +45,15 @@ def validate_mode(value):
CONF_MCP23016 = "mcp23016" CONF_MCP23016 = "mcp23016"
MCP23016_PIN_SCHEMA = cv.All( MCP23016_PIN_SCHEMA = pins.gpio_base_schema(
MCP23016GPIOPin,
cv.int_range(min=0, max=15),
modes=[CONF_INPUT, CONF_OUTPUT],
mode_validator=validate_mode,
invertable=True,
).extend(
{ {
cv.GenerateID(): cv.declare_id(MCP23016GPIOPin),
cv.Required(CONF_MCP23016): cv.use_id(MCP23016), cv.Required(CONF_MCP23016): cv.use_id(MCP23016),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=15),
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
},
validate_mode,
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
} }
) )

View file

@ -54,20 +54,16 @@ def validate_mode(value):
CONF_MCP23XXX = "mcp23xxx" CONF_MCP23XXX = "mcp23xxx"
MCP23XXX_PIN_SCHEMA = cv.All(
MCP23XXX_PIN_SCHEMA = pins.gpio_base_schema(
MCP23XXXGPIOPin,
cv.int_range(min=0, max=15),
modes=[CONF_INPUT, CONF_OUTPUT, CONF_PULLUP],
mode_validator=validate_mode,
invertable=True,
).extend(
{ {
cv.GenerateID(): cv.declare_id(MCP23XXXGPIOPin),
cv.Required(CONF_MCP23XXX): cv.use_id(MCP23XXXBase), cv.Required(CONF_MCP23XXX): cv.use_id(MCP23XXXBase),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=15),
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
},
validate_mode,
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
cv.Optional(CONF_INTERRUPT, default="NO_INTERRUPT"): cv.enum( cv.Optional(CONF_INTERRUPT, default="NO_INTERRUPT"): cv.enum(
MCP23XXX_INTERRUPT_MODES, upper=True MCP23XXX_INTERRUPT_MODES, upper=True
), ),

View file

@ -76,7 +76,11 @@ bool MQTTComponent::send_discovery_() {
this->send_discovery(root, config); this->send_discovery(root, config);
// Fields from EntityBase // Fields from EntityBase
root[MQTT_NAME] = this->friendly_name(); if (this->get_entity()->has_own_name()) {
root[MQTT_NAME] = this->friendly_name();
} else {
root[MQTT_NAME] = "";
}
if (this->is_disabled_by_default()) if (this->is_disabled_by_default())
root[MQTT_ENABLED_BY_DEFAULT] = false; root[MQTT_ENABLED_BY_DEFAULT] = false;
if (!this->get_icon().empty()) if (!this->get_icon().empty())

View file

@ -29,6 +29,7 @@ CONF_BACKGROUND_PRESSED_COLOR = "background_pressed_color"
CONF_FOREGROUND_COLOR = "foreground_color" CONF_FOREGROUND_COLOR = "foreground_color"
CONF_FOREGROUND_PRESSED_COLOR = "foreground_pressed_color" CONF_FOREGROUND_PRESSED_COLOR = "foreground_pressed_color"
CONF_FONT_ID = "font_id" CONF_FONT_ID = "font_id"
CONF_EXIT_REPARSE_ON_START = "exit_reparse_on_start"
def NextionName(value): def NextionName(value):

View file

@ -21,6 +21,7 @@ from .base_component import (
CONF_WAKE_UP_PAGE, CONF_WAKE_UP_PAGE,
CONF_START_UP_PAGE, CONF_START_UP_PAGE,
CONF_AUTO_WAKE_ON_TOUCH, CONF_AUTO_WAKE_ON_TOUCH,
CONF_EXIT_REPARSE_ON_START,
) )
CODEOWNERS = ["@senexcrenshaw"] CODEOWNERS = ["@senexcrenshaw"]
@ -69,6 +70,7 @@ CONFIG_SCHEMA = (
cv.Optional(CONF_WAKE_UP_PAGE): cv.positive_int, cv.Optional(CONF_WAKE_UP_PAGE): cv.positive_int,
cv.Optional(CONF_START_UP_PAGE): cv.positive_int, cv.Optional(CONF_START_UP_PAGE): cv.positive_int,
cv.Optional(CONF_AUTO_WAKE_ON_TOUCH, default=True): cv.boolean, cv.Optional(CONF_AUTO_WAKE_ON_TOUCH, default=True): cv.boolean,
cv.Optional(CONF_EXIT_REPARSE_ON_START, default=False): cv.boolean,
} }
) )
.extend(cv.polling_component_schema("5s")) .extend(cv.polling_component_schema("5s"))
@ -106,8 +108,9 @@ async def to_code(config):
if CONF_START_UP_PAGE in config: if CONF_START_UP_PAGE in config:
cg.add(var.set_start_up_page_internal(config[CONF_START_UP_PAGE])) cg.add(var.set_start_up_page_internal(config[CONF_START_UP_PAGE]))
if CONF_AUTO_WAKE_ON_TOUCH in config: cg.add(var.set_auto_wake_on_touch_internal(config[CONF_AUTO_WAKE_ON_TOUCH]))
cg.add(var.set_auto_wake_on_touch_internal(config[CONF_AUTO_WAKE_ON_TOUCH]))
cg.add(var.set_exit_reparse_on_start_internal(config[CONF_EXIT_REPARSE_ON_START]))
await display.register_display(var, config) await display.register_display(var, config)

View file

@ -2,6 +2,7 @@
#include "esphome/core/util.h" #include "esphome/core/util.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/application.h" #include "esphome/core/application.h"
#include <cinttypes>
namespace esphome { namespace esphome {
namespace nextion { namespace nextion {
@ -47,6 +48,9 @@ bool Nextion::check_connect_() {
this->ignore_is_setup_ = true; this->ignore_is_setup_ = true;
this->send_command_("boguscommand=0"); // bogus command. needed sometimes after updating this->send_command_("boguscommand=0"); // bogus command. needed sometimes after updating
if (this->exit_reparse_on_start_) {
this->send_command_("DRAKJHSUYDGBNCJHGJKSHBDN");
}
this->send_command_("connect"); this->send_command_("connect");
this->comok_sent_ = millis(); this->comok_sent_ = millis();
@ -126,7 +130,8 @@ void Nextion::dump_config() {
ESP_LOGCONFIG(TAG, " Firmware Version: %s", this->firmware_version_.c_str()); ESP_LOGCONFIG(TAG, " Firmware Version: %s", this->firmware_version_.c_str());
ESP_LOGCONFIG(TAG, " Serial Number: %s", this->serial_number_.c_str()); ESP_LOGCONFIG(TAG, " Serial Number: %s", this->serial_number_.c_str());
ESP_LOGCONFIG(TAG, " Flash Size: %s", this->flash_size_.c_str()); ESP_LOGCONFIG(TAG, " Flash Size: %s", this->flash_size_.c_str());
ESP_LOGCONFIG(TAG, " Wake On Touch: %s", this->auto_wake_on_touch_ ? "True" : "False"); ESP_LOGCONFIG(TAG, " Wake On Touch: %s", YESNO(this->auto_wake_on_touch_));
ESP_LOGCONFIG(TAG, " Exit reparse: %s", YESNO(this->exit_reparse_on_start_));
if (this->touch_sleep_timeout_ != 0) { if (this->touch_sleep_timeout_ != 0) {
ESP_LOGCONFIG(TAG, " Touch Timeout: %" PRIu32, this->touch_sleep_timeout_); ESP_LOGCONFIG(TAG, " Touch Timeout: %" PRIu32, this->touch_sleep_timeout_);
@ -247,6 +252,7 @@ void Nextion::loop() {
} }
this->set_auto_wake_on_touch(this->auto_wake_on_touch_); this->set_auto_wake_on_touch(this->auto_wake_on_touch_);
this->set_exit_reparse_on_start(this->exit_reparse_on_start_);
if (this->touch_sleep_timeout_ != 0) { if (this->touch_sleep_timeout_ != 0) {
this->set_touch_sleep_timeout(this->touch_sleep_timeout_); this->set_touch_sleep_timeout(this->touch_sleep_timeout_);

View file

@ -815,6 +815,19 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
* The display will wake up by touch. * The display will wake up by touch.
*/ */
void set_auto_wake_on_touch(bool auto_wake); void set_auto_wake_on_touch(bool auto_wake);
/**
* Sets if Nextion should exit the active reparse mode before the "connect" command is sent
* @param exit_reparse True or false. When exit_reparse is true, the exit reparse command
* will be sent before requesting the connection from Nextion.
*
* Example:
* ```cpp
* it.set_exit_reparse_on_start(true);
* ```
*
* The display will be requested to leave active reparse mode before setup.
*/
void set_exit_reparse_on_start(bool exit_reparse);
/** /**
* Sets Nextion mode between sleep and awake * Sets Nextion mode between sleep and awake
* @param True or false. Sleep=true to enter sleep mode or sleep=false to exit sleep mode. * @param True or false. Sleep=true to enter sleep mode or sleep=false to exit sleep mode.
@ -943,6 +956,9 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
void set_wake_up_page_internal(uint8_t wake_up_page) { this->wake_up_page_ = wake_up_page; } void set_wake_up_page_internal(uint8_t wake_up_page) { this->wake_up_page_ = wake_up_page; }
void set_start_up_page_internal(uint8_t start_up_page) { this->start_up_page_ = start_up_page; } void set_start_up_page_internal(uint8_t start_up_page) { this->start_up_page_ = start_up_page; }
void set_auto_wake_on_touch_internal(bool auto_wake_on_touch) { this->auto_wake_on_touch_ = auto_wake_on_touch; } void set_auto_wake_on_touch_internal(bool auto_wake_on_touch) { this->auto_wake_on_touch_ = auto_wake_on_touch; }
void set_exit_reparse_on_start_internal(bool exit_reparse_on_start) {
this->exit_reparse_on_start_ = exit_reparse_on_start;
}
protected: protected:
std::deque<NextionQueue *> nextion_queue_; std::deque<NextionQueue *> nextion_queue_;
@ -966,6 +982,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
int wake_up_page_ = -1; int wake_up_page_ = -1;
int start_up_page_ = -1; int start_up_page_ = -1;
bool auto_wake_on_touch_ = true; bool auto_wake_on_touch_ = true;
bool exit_reparse_on_start_ = false;
/** /**
* Manually send a raw command to the display and don't wait for an acknowledgement packet. * Manually send a raw command to the display and don't wait for an acknowledgement packet.

View file

@ -1,6 +1,7 @@
#include "nextion.h" #include "nextion.h"
#include "esphome/core/util.h" #include "esphome/core/util.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <cinttypes>
namespace esphome { namespace esphome {
namespace nextion { namespace nextion {
@ -52,6 +53,7 @@ void Nextion::set_protocol_reparse_mode(bool active_mode) {
this->write_str("connect"); this->write_str("connect");
this->write_array(to_send, sizeof(to_send)); this->write_array(to_send, sizeof(to_send));
} }
void Nextion::set_exit_reparse_on_start(bool exit_reparse) { this->exit_reparse_on_start_ = exit_reparse; }
// Set Colors - Background // Set Colors - Background
void Nextion::set_component_background_color(const char *component, uint16_t color) { void Nextion::set_component_background_color(const char *component, uint16_t color) {

View file

@ -15,7 +15,7 @@
namespace esphome { namespace esphome {
namespace nextion { namespace nextion {
static const char *const TAG = "nextion_upload"; static const char *const TAG = "nextion.upload.arduino";
// Followed guide // Followed guide
// https://unofficialnextion.com/t/nextion-upload-protocol-v1-2-the-fast-one/1044/2 // https://unofficialnextion.com/t/nextion-upload-protocol-v1-2-the-fast-one/1044/2

View file

@ -11,10 +11,11 @@
#include <esp_heap_caps.h> #include <esp_heap_caps.h>
#include <esp_http_client.h> #include <esp_http_client.h>
#include <cinttypes>
namespace esphome { namespace esphome {
namespace nextion { namespace nextion {
static const char *const TAG = "nextion_upload"; static const char *const TAG = "nextion.upload.idf";
// Followed guide // Followed guide
// https://unofficialnextion.com/t/nextion-upload-protocol-v1-2-the-fast-one/1044/2 // https://unofficialnextion.com/t/nextion-upload-protocol-v1-2-the-fast-one/1044/2

View file

@ -52,20 +52,15 @@ def validate_mode(value):
return value return value
PCA9554_PIN_SCHEMA = cv.All( PCA9554_PIN_SCHEMA = pins.gpio_base_schema(
PCA9554GPIOPin,
cv.int_range(min=0, max=15),
modes=[CONF_INPUT, CONF_OUTPUT],
mode_validator=validate_mode,
).extend(
{ {
cv.GenerateID(): cv.declare_id(PCA9554GPIOPin),
cv.Required(CONF_PCA9554): cv.use_id(PCA9554Component), cv.Required(CONF_PCA9554): cv.use_id(PCA9554Component),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=15), }
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
},
validate_mode,
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
},
) )

View file

@ -48,19 +48,15 @@ def validate_mode(value):
return value return value
PCF8574_PIN_SCHEMA = cv.All( PCF8574_PIN_SCHEMA = pins.gpio_base_schema(
PCF8574GPIOPin,
cv.int_range(min=0, max=17),
modes=[CONF_INPUT, CONF_OUTPUT],
mode_validator=validate_mode,
invertable=True,
).extend(
{ {
cv.GenerateID(): cv.declare_id(PCF8574GPIOPin),
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component), cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=17),
cv.Optional(CONF_MODE, default={}): cv.All(
{
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
},
validate_mode,
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
} }
) )

View file

@ -397,8 +397,10 @@ RC522::StatusCode RC522::await_transceive_() {
back_length_ = 0; back_length_ = 0;
ESP_LOGW(TAG, "Communication with the MFRC522 might be down, reset in %d", ESP_LOGW(TAG, "Communication with the MFRC522 might be down, reset in %d",
10 - error_counter_); // todo: trigger reset? 10 - error_counter_); // todo: trigger reset?
if (error_counter_++ > 10) if (error_counter_++ >= 10) {
setup(); setup();
error_counter_ = 0; // reset the error counter
}
return STATUS_TIMEOUT; return STATUS_TIMEOUT;
} }

View file

@ -1,7 +1,6 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import ( from esphome.const import (
CONF_ANALOG,
CONF_ID, CONF_ID,
CONF_INPUT, CONF_INPUT,
CONF_INVERTED, CONF_INVERTED,
@ -11,6 +10,7 @@ from esphome.const import (
CONF_OUTPUT, CONF_OUTPUT,
CONF_PULLDOWN, CONF_PULLDOWN,
CONF_PULLUP, CONF_PULLUP,
CONF_ANALOG,
) )
from esphome.core import CORE from esphome.core import CORE
from esphome import pins from esphome import pins
@ -78,22 +78,10 @@ def validate_supports(value):
RP2040_PIN_SCHEMA = cv.All( RP2040_PIN_SCHEMA = cv.All(
cv.Schema( pins.gpio_base_schema(
{ RP2040GPIOPin,
cv.GenerateID(): cv.declare_id(RP2040GPIOPin), validate_gpio_pin,
cv.Required(CONF_NUMBER): validate_gpio_pin, modes=pins.GPIO_STANDARD_MODES + (CONF_ANALOG,),
cv.Optional(CONF_MODE, default={}): cv.Schema(
{
cv.Optional(CONF_ANALOG, default=False): cv.boolean,
cv.Optional(CONF_INPUT, default=False): cv.boolean,
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
}
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
}
), ),
validate_supports, validate_supports,
) )

View file

@ -5,7 +5,6 @@ from esphome.components import spi
from esphome.const import ( from esphome.const import (
CONF_ID, CONF_ID,
CONF_SPI_ID, CONF_SPI_ID,
CONF_MODE,
CONF_NUMBER, CONF_NUMBER,
CONF_INVERTED, CONF_INVERTED,
CONF_DATA_PIN, CONF_DATA_PIN,
@ -35,7 +34,6 @@ CONF_LATCH_PIN = "latch_pin"
CONF_OE_PIN = "oe_pin" CONF_OE_PIN = "oe_pin"
CONF_SR_COUNT = "sr_count" CONF_SR_COUNT = "sr_count"
CONFIG_SCHEMA = cv.Any( CONFIG_SCHEMA = cv.Any(
cv.Schema( cv.Schema(
{ {
@ -88,24 +86,20 @@ async def to_code(config):
def _validate_output_mode(value): def _validate_output_mode(value):
if value is not True: if value.get(CONF_OUTPUT) is not True:
raise cv.Invalid("Only output mode is supported") raise cv.Invalid("Only output mode is supported")
return value return value
SN74HC595_PIN_SCHEMA = cv.All( SN74HC595_PIN_SCHEMA = pins.gpio_base_schema(
SN74HC595GPIOPin,
cv.int_range(min=0, max=2047),
modes=[CONF_OUTPUT],
mode_validator=_validate_output_mode,
invertable=True,
).extend(
{ {
cv.GenerateID(): cv.declare_id(SN74HC595GPIOPin),
cv.Required(CONF_SN74HC595): cv.use_id(SN74HC595Component), cv.Required(CONF_SN74HC595): cv.use_id(SN74HC595Component),
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(
cv.boolean, _validate_output_mode
),
},
),
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
} }
) )

View file

@ -39,8 +39,8 @@ def validate(config):
) )
with cv.prepend_path(CONF_MIN_LENGTH): with cv.prepend_path(CONF_MIN_LENGTH):
if config[CONF_MIN_LENGTH] >= config[CONF_MAX_LENGTH]: if config[CONF_MIN_LENGTH] > config[CONF_MAX_LENGTH]:
raise cv.Invalid("min_length must be less than max_length") raise cv.Invalid("min_length must be less than or equal to max_length")
return config return config

View file

@ -164,7 +164,7 @@ void WiFiComponent::loop() {
#ifdef USE_WIFI_AP #ifdef USE_WIFI_AP
if (this->has_ap() && !this->ap_setup_) { if (this->has_ap() && !this->ap_setup_) {
if (now - this->last_connected_ > this->ap_timeout_) { if (this->ap_timeout_ != 0 && (now - this->last_connected_ > this->ap_timeout_)) {
ESP_LOGI(TAG, "Starting fallback AP!"); ESP_LOGI(TAG, "Starting fallback AP!");
this->setup_ap_config_(); this->setup_ap_config_();
#ifdef USE_CAPTIVE_PORTAL #ifdef USE_CAPTIVE_PORTAL

View file

@ -7,6 +7,7 @@ import re
from typing import Optional, Union from typing import Optional, Union
from contextlib import contextmanager from contextlib import contextmanager
import contextvars
import voluptuous as vol import voluptuous as vol
@ -25,7 +26,7 @@ from esphome.core import CORE, EsphomeError
from esphome.helpers import indent from esphome.helpers import indent
from esphome.util import safe_print, OrderedDict from esphome.util import safe_print, OrderedDict
from esphome.config_helpers import Extend from esphome.config_helpers import Extend, Remove
from esphome.loader import get_component, get_platform, ComponentManifest from esphome.loader import get_component, get_platform, ComponentManifest
from esphome.yaml_util import is_secret, ESPHomeDataBase, ESPForceValue from esphome.yaml_util import is_secret, ESPHomeDataBase, ESPForceValue
from esphome.voluptuous_schema import ExtraKeysInvalid from esphome.voluptuous_schema import ExtraKeysInvalid
@ -53,6 +54,7 @@ def iter_components(config):
ConfigPath = list[Union[str, int]] ConfigPath = list[Union[str, int]]
path_context = contextvars.ContextVar("Config path")
def _path_begins_with(path: ConfigPath, other: ConfigPath) -> bool: def _path_begins_with(path: ConfigPath, other: ConfigPath) -> bool:
@ -343,6 +345,12 @@ class LoadValidationStep(ConfigValidationStep):
path + [CONF_ID], path + [CONF_ID],
) )
continue continue
if isinstance(p_id, Remove):
result.add_str_error(
f"Source for removal of ID '{p_id.value}' was not found.",
path + [CONF_ID],
)
continue
result.add_str_error("No platform specified! See 'platform' key.", path) result.add_str_error("No platform specified! See 'platform' key.", path)
continue continue
# Remove temp output path and construct new one # Remove temp output path and construct new one
@ -489,6 +497,7 @@ class SchemaValidationStep(ConfigValidationStep):
def run(self, result: Config) -> None: def run(self, result: Config) -> None:
if self.comp.config_schema is None: if self.comp.config_schema is None:
return return
token = path_context.set(self.path)
with result.catch_error(self.path): with result.catch_error(self.path):
if self.comp.is_platform: if self.comp.is_platform:
# Remove 'platform' key for validation # Remove 'platform' key for validation
@ -507,6 +516,7 @@ class SchemaValidationStep(ConfigValidationStep):
validated = schema(self.conf) validated = schema(self.conf)
result.set_by_path(self.path, validated) result.set_by_path(self.path, validated)
path_context.reset(token)
result.add_validation_step(FinalValidateValidationStep(self.path, self.comp)) result.add_validation_step(FinalValidateValidationStep(self.path, self.comp))
@ -630,6 +640,35 @@ class IDPassValidationStep(ConfigValidationStep):
) )
class RemoveReferenceValidationStep(ConfigValidationStep):
"""
Make sure all !remove references have been removed from the config.
Any left overs mean the merge step couldn't find corresponding previously existing id/key
"""
def run(self, result: Config) -> None:
if result.errors:
# If result already has errors, skip this step
return
def recursive_check_remove_tag(config: Config, path: ConfigPath = None):
path = path or []
if isinstance(config, Remove):
result.add_str_error(
f"Source for removal at '{'->'.join([str(p) for p in path])}' was not found.",
path,
)
elif isinstance(config, list):
for i, item in enumerate(config):
recursive_check_remove_tag(item, path + [i])
elif isinstance(config, dict):
for key, value in config.items():
recursive_check_remove_tag(value, path + [key])
recursive_check_remove_tag(result)
class FinalValidateValidationStep(ConfigValidationStep): class FinalValidateValidationStep(ConfigValidationStep):
"""Run final_validate_schema for all components.""" """Run final_validate_schema for all components."""
@ -652,37 +691,24 @@ class FinalValidateValidationStep(ConfigValidationStep):
if self.comp.final_validate_schema is not None: if self.comp.final_validate_schema is not None:
self.comp.final_validate_schema(conf) self.comp.final_validate_schema(conf)
fconf = fv.full_config.get()
def _check_pins(c):
for value in c.values():
if not isinstance(value, dict):
continue
for key, (
_,
_,
pin_final_validate,
) in pins.PIN_SCHEMA_REGISTRY.items():
if (
key != CORE.target_platform
and key in value
and pin_final_validate is not None
):
pin_final_validate(fconf, value)
# Check for pin configs and a final_validate schema in the pin registry
confs = conf
if not isinstance(
confs, list
): # Handle components like SPI that have a list instead of MULTI_CONF
confs = [conf]
for c in confs:
if c: # Some component have None or empty schemas
_check_pins(c)
fv.full_config.reset(token) fv.full_config.reset(token)
class PinUseValidationCheck(ConfigValidationStep):
"""Check for pin reuse"""
priority = -30 # Should happen after component final validations
def __init__(self) -> None:
pass
def run(self, result: Config) -> None:
if result.errors:
# If result already has errors, skip this step
return
pins.PIN_SCHEMA_REGISTRY.final_validate(result)
def validate_config(config, command_line_substitutions) -> Config: def validate_config(config, command_line_substitutions) -> Config:
result = Config() result = Config()
@ -778,6 +804,9 @@ def validate_config(config, command_line_substitutions) -> Config:
for domain, conf in config.items(): for domain, conf in config.items():
result.add_validation_step(LoadValidationStep(domain, conf)) result.add_validation_step(LoadValidationStep(domain, conf))
result.add_validation_step(IDPassValidationStep()) result.add_validation_step(IDPassValidationStep())
result.add_validation_step(PinUseValidationCheck())
result.add_validation_step(RemoveReferenceValidationStep())
result.run_validation_steps() result.run_validation_steps()

View file

@ -22,6 +22,22 @@ class Extend:
return isinstance(b, Extend) and self.value == b.value return isinstance(b, Extend) and self.value == b.value
class Remove:
def __init__(self, value=None):
self.value = value
def __str__(self):
return f"!remove {self.value}"
def __eq__(self, b):
"""
Check if two Remove objects contain the same ID.
Only used in unit tests.
"""
return isinstance(b, Remove) and self.value == b.value
def read_config_file(path: str) -> str: def read_config_file(path: str) -> str:
if CORE.vscode and ( if CORE.vscode and (
not CORE.ace or os.path.abspath(path) == os.path.abspath(CORE.config_path) not CORE.ace or os.path.abspath(path) == os.path.abspath(CORE.config_path)
@ -48,7 +64,10 @@ def merge_config(full_old, full_new):
return new return new
res = old.copy() res = old.copy()
for k, v in new.items(): for k, v in new.items():
res[k] = merge(old[k], v) if k in old else v if isinstance(v, Remove) and k in old:
del res[k]
else:
res[k] = merge(old[k], v) if k in old else v
return res return res
if isinstance(new, list): if isinstance(new, list):
if not isinstance(old, list): if not isinstance(old, list):
@ -59,6 +78,7 @@ def merge_config(full_old, full_new):
for i, v in enumerate(res) for i, v in enumerate(res)
if CONF_ID in v and isinstance(v[CONF_ID], str) if CONF_ID in v and isinstance(v[CONF_ID], str)
} }
ids_to_delete = []
for v in new: for v in new:
if CONF_ID in v: if CONF_ID in v:
new_id = v[CONF_ID] new_id = v[CONF_ID]
@ -68,9 +88,15 @@ def merge_config(full_old, full_new):
v[CONF_ID] = new_id v[CONF_ID] = new_id
res[ids[new_id]] = merge(res[ids[new_id]], v) res[ids[new_id]] = merge(res[ids[new_id]], v)
continue continue
elif isinstance(new_id, Remove):
new_id = new_id.value
if new_id in ids:
ids_to_delete.append(ids[new_id])
continue
else: else:
ids[new_id] = len(res) ids[new_id] = len(res)
res.append(v) res.append(v)
res = [v for i, v in enumerate(res) if i not in ids_to_delete]
return res return res
if new is None: if new is None:
return old return old

View file

@ -13,7 +13,7 @@ import voluptuous as vol
from esphome import core from esphome import core
import esphome.codegen as cg import esphome.codegen as cg
from esphome.config_helpers import Extend from esphome.config_helpers import Extend, Remove
from esphome.const import ( from esphome.const import (
ALLOWED_NAME_CHARS, ALLOWED_NAME_CHARS,
CONF_AVAILABILITY, CONF_AVAILABILITY,
@ -532,6 +532,10 @@ def declare_id(type):
if isinstance(value, Extend): if isinstance(value, Extend):
raise Invalid(f"Source for extension of ID '{value.value}' was not found.") raise Invalid(f"Source for extension of ID '{value.value}' was not found.")
if isinstance(value, Remove):
raise Invalid(f"Source for Removal of ID '{value.value}' was not found.")
return core.ID(validate_id_name(value), is_declaration=True, type=type) return core.ID(validate_id_name(value), is_declaration=True, type=type)
return validator return validator

View file

@ -46,6 +46,7 @@ CONF_ADDRESS = "address"
CONF_ADDRESSABLE_LIGHT_ID = "addressable_light_id" CONF_ADDRESSABLE_LIGHT_ID = "addressable_light_id"
CONF_ADVANCED = "advanced" CONF_ADVANCED = "advanced"
CONF_AFTER = "after" CONF_AFTER = "after"
CONF_ALLOW_OTHER_USES = "allow_other_uses"
CONF_ALPHA = "alpha" CONF_ALPHA = "alpha"
CONF_ALTITUDE = "altitude" CONF_ALTITUDE = "altitude"
CONF_ANALOG = "analog" CONF_ANALOG = "analog"

View file

@ -522,8 +522,12 @@ class EsphomeCore:
self.component_ids = set() self.component_ids = set()
# Whether ESPHome was started in verbose mode # Whether ESPHome was started in verbose mode
self.verbose = False self.verbose = False
# Whether ESPHome was started in quiet mode
self.quiet = False
def reset(self): def reset(self):
from esphome.pins import PIN_SCHEMA_REGISTRY
self.dashboard = False self.dashboard = False
self.name = None self.name = None
self.friendly_name = None self.friendly_name = None
@ -543,6 +547,7 @@ class EsphomeCore:
self.platformio_options = {} self.platformio_options = {}
self.loaded_integrations = set() self.loaded_integrations = set()
self.component_ids = set() self.component_ids = set()
PIN_SCHEMA_REGISTRY.reset()
@property @property
def address(self) -> Optional[str]: def address(self) -> Optional[str]:

View file

@ -78,6 +78,7 @@ def setup_log(
CORE.verbose = True CORE.verbose = True
elif quiet: elif quiet:
log_level = logging.CRITICAL log_level = logging.CRITICAL
CORE.quiet = True
else: else:
log_level = logging.INFO log_level = logging.INFO
logging.basicConfig(level=log_level) logging.basicConfig(level=log_level)

View file

@ -1,5 +1,7 @@
import operator import operator
from functools import reduce from functools import reduce
import esphome.config_validation as cv
from esphome.core import CORE, ID
from esphome.const import ( from esphome.const import (
CONF_INPUT, CONF_INPUT,
@ -10,16 +12,120 @@ from esphome.const import (
CONF_PULLDOWN, CONF_PULLDOWN,
CONF_PULLUP, CONF_PULLUP,
CONF_IGNORE_STRAPPING_WARNING, CONF_IGNORE_STRAPPING_WARNING,
CONF_ALLOW_OTHER_USES,
CONF_INVERTED,
) )
from esphome.util import PinRegistry
from esphome.core import CORE
class PinRegistry(dict):
def __init__(self):
super().__init__()
self.pins_used = {}
def reset(self):
self.pins_used = {}
def get_count(self, key, number):
"""
Get the number of places a given pin is used.
:param key: The ID of the defining component
:param number: The pin number
:return: The number of places the pin is used.
"""
pin_key = (key, number)
return self.pins_used[pin_key] if pin_key in self.pins_used else 0
def register(self, name, schema, final_validate=None):
"""
Register a pin schema
:param name:
:param schema:
:param final_validate:
:return:
"""
def decorator(fun):
self[name] = (fun, schema, final_validate)
return fun
return decorator
def validate(self, conf, key=None):
"""
Validate a pin against a registered schema
:param conf The pin config
:param key: an optional scalar key (e.g. platform)
:return: The transformed result
"""
from esphome.config import path_context
key = self.get_key(conf) if key is None else key
# Element 1 is the pin validation function
# evaluate here so a validation failure skips the rest
result = self[key][1](conf)
if CONF_NUMBER in result:
# key maps to the pin schema
if isinstance(key, ID):
key = key.id
pin_key = (key, result[CONF_NUMBER])
if pin_key not in self.pins_used:
self.pins_used[pin_key] = []
# client_id identifies the instance of the providing component
client_id = result.get(key)
self.pins_used[pin_key].append((path_context.get(), client_id, result))
# return the validated pin config
return result
def get_key(self, conf):
"""
Is there a key in conf corresponding to a registered pin schema?
If not, fall back to the default platform schema.
:param conf The config for the component
:return: the schema key
"""
keys = list(filter(lambda k: k in conf, self))
return keys[0] if keys else CORE.target_platform
def get_to_code(self, key):
"""
Return the code generator function for a pin schema, stored as tuple element 0
:param conf: The pin config
:param key An optional specific key
:return: The awaitable coroutine
"""
key = self.get_key(key) if isinstance(key, dict) else key
return self[key][0]
def final_validate(self, fconf):
"""
Run the final validation for all pins, and check for reuse
:param fconf: The full config
"""
for (key, _), pin_list in self.pins_used.items():
count = len(pin_list) # number of places same pin used.
final_val_fun = self[key][2] # final validation function
for pin_path, client_id, pin_config in pin_list:
with fconf.catch_error([cv.ROOT_CONFIG_PATH] + pin_path):
if final_val_fun is not None:
# Get the containing path of the config providing this pin.
parent_path = fconf.get_path_for_id(client_id)[:-1]
parent_config = fconf.get_config_for_path(parent_path)
final_val_fun(pin_config, parent_config)
allow_others = pin_config.get(CONF_ALLOW_OTHER_USES, False)
if count != 1 and not allow_others:
raise cv.Invalid(
f"Pin {pin_config[CONF_NUMBER]} is used in multiple places"
)
if count == 1 and allow_others:
raise cv.Invalid(
f"Pin {pin_config[CONF_NUMBER]} incorrectly sets {CONF_ALLOW_OTHER_USES}: true"
)
PIN_SCHEMA_REGISTRY = PinRegistry() PIN_SCHEMA_REGISTRY = PinRegistry()
def _set_mode(value, default_mode): def _set_mode(value, default_mode):
import esphome.config_validation as cv
if CONF_MODE not in value: if CONF_MODE not in value:
return {**value, CONF_MODE: default_mode} return {**value, CONF_MODE: default_mode}
mode = value[CONF_MODE] mode = value[CONF_MODE]
@ -65,20 +171,26 @@ def _schema_creator(default_mode, internal: bool = False):
if not isinstance(value, dict): if not isinstance(value, dict):
return validator({CONF_NUMBER: value}) return validator({CONF_NUMBER: value})
value = _set_mode(value, default_mode) value = _set_mode(value, default_mode)
if not internal: if internal:
for key, entry in PIN_SCHEMA_REGISTRY.items(): return PIN_SCHEMA_REGISTRY.validate(value, CORE.target_platform)
if key != CORE.target_platform and key in value: return PIN_SCHEMA_REGISTRY.validate(value)
return entry[1](value)
return PIN_SCHEMA_REGISTRY[CORE.target_platform][1](value)
return validator return validator
def _internal_number_creator(mode): def _internal_number_creator(mode):
def validator(value): def validator(value):
value_d = {CONF_NUMBER: value} if isinstance(value, dict):
if CONF_MODE in value or CONF_INVERTED in value:
raise cv.Invalid(
"This variable only supports pin numbers, not full pin schemas "
"(with inverted and mode)."
)
value_d = value
else:
value_d = {CONF_NUMBER: value}
value_d = _set_mode(value_d, mode) value_d = _set_mode(value_d, mode)
return PIN_SCHEMA_REGISTRY[CORE.target_platform][1](value_d)[CONF_NUMBER] return PIN_SCHEMA_REGISTRY.validate(value_d, CORE.target_platform)[CONF_NUMBER]
return validator return validator
@ -149,8 +261,6 @@ internal_gpio_input_pullup_pin_number = _internal_number_creator(
def check_strapping_pin(conf, strapping_pin_list, logger): def check_strapping_pin(conf, strapping_pin_list, logger):
import esphome.config_validation as cv
num = conf[CONF_NUMBER] num = conf[CONF_NUMBER]
if num in strapping_pin_list and not conf.get(CONF_IGNORE_STRAPPING_WARNING): if num in strapping_pin_list and not conf.get(CONF_IGNORE_STRAPPING_WARNING):
logger.warning( logger.warning(
@ -161,3 +271,52 @@ def check_strapping_pin(conf, strapping_pin_list, logger):
# mitigate undisciplined use of strapping: # mitigate undisciplined use of strapping:
if num not in strapping_pin_list and conf.get(CONF_IGNORE_STRAPPING_WARNING): if num not in strapping_pin_list and conf.get(CONF_IGNORE_STRAPPING_WARNING):
raise cv.Invalid(f"GPIO{num} is not a strapping pin") raise cv.Invalid(f"GPIO{num} is not a strapping pin")
GPIO_STANDARD_MODES = (
CONF_INPUT,
CONF_OUTPUT,
CONF_OPEN_DRAIN,
CONF_PULLUP,
CONF_PULLDOWN,
)
def gpio_validate_modes(value):
if not value[CONF_INPUT] and not value[CONF_OUTPUT]:
raise cv.Invalid("Mode must be input or output")
return value
def gpio_base_schema(
pin_type,
number_validator,
modes=GPIO_STANDARD_MODES,
mode_validator=gpio_validate_modes,
invertable=True,
):
"""
Generate a base gpio pin schema
:param pin_type: The type for the pin variable
:param number_validator: A validator for the pin number
:param modes: The available modes, default is all standard modes
:param mode_validator: A validator function for the pin mode
:param invertable: If the pin supports hardware inversion
:return: A schema for the pin
"""
mode_default = len(modes) == 1
mode_dict = dict(
map(lambda m: (cv.Optional(m, default=mode_default), cv.boolean), modes)
)
schema = cv.Schema(
{
cv.GenerateID(): cv.declare_id(pin_type),
cv.Required(CONF_NUMBER): number_validator,
cv.Optional(CONF_ALLOW_OTHER_USES): cv.boolean,
cv.Optional(CONF_MODE, default={}): cv.All(mode_dict, mode_validator),
}
)
if invertable:
return schema.extend({cv.Optional(CONF_INVERTED, default=False): cv.boolean})
return schema

View file

@ -57,32 +57,6 @@ class SimpleRegistry(dict):
return decorator return decorator
def _final_validate(parent_id_key, fun):
def validator(fconf, pin_config):
import esphome.config_validation as cv
parent_path = fconf.get_path_for_id(pin_config[parent_id_key])[:-1]
parent_config = fconf.get_config_for_path(parent_path)
pin_path = fconf.get_path_for_id(pin_config[const.CONF_ID])[:-1]
with cv.prepend_path([cv.ROOT_CONFIG_PATH] + pin_path):
fun(pin_config, parent_config)
return validator
class PinRegistry(dict):
def register(self, name, schema, final_validate=None):
if final_validate is not None:
final_validate = _final_validate(name, final_validate)
def decorator(fun):
self[name] = (fun, schema, final_validate)
return fun
return decorator
def safe_print(message="", end="\n"): def safe_print(message="", end="\n"):
from esphome.core import CORE from esphome.core import CORE

View file

@ -10,7 +10,7 @@ import yaml
import yaml.constructor import yaml.constructor
from esphome import core from esphome import core
from esphome.config_helpers import read_config_file, Extend from esphome.config_helpers import read_config_file, Extend, Remove
from esphome.core import ( from esphome.core import (
EsphomeError, EsphomeError,
IPAddress, IPAddress,
@ -362,6 +362,10 @@ class ESPHomeLoader(FastestAvailableSafeLoader):
def construct_extend(self, node): def construct_extend(self, node):
return Extend(str(node.value)) return Extend(str(node.value))
@_add_data_ref
def construct_remove(self, node):
return Remove(str(node.value))
ESPHomeLoader.add_constructor("tag:yaml.org,2002:int", ESPHomeLoader.construct_yaml_int) ESPHomeLoader.add_constructor("tag:yaml.org,2002:int", ESPHomeLoader.construct_yaml_int)
ESPHomeLoader.add_constructor( ESPHomeLoader.add_constructor(
@ -394,6 +398,7 @@ ESPHomeLoader.add_constructor(
ESPHomeLoader.add_constructor("!lambda", ESPHomeLoader.construct_lambda) ESPHomeLoader.add_constructor("!lambda", ESPHomeLoader.construct_lambda)
ESPHomeLoader.add_constructor("!force", ESPHomeLoader.construct_force) ESPHomeLoader.add_constructor("!force", ESPHomeLoader.construct_force)
ESPHomeLoader.add_constructor("!extend", ESPHomeLoader.construct_extend) ESPHomeLoader.add_constructor("!extend", ESPHomeLoader.construct_extend)
ESPHomeLoader.add_constructor("!remove", ESPHomeLoader.construct_remove)
def load_yaml(fname, clear_secrets=True): def load_yaml(fname, clear_secrets=True):

View file

@ -1,4 +1,4 @@
voluptuous==0.13.1 voluptuous==0.14.1
PyYAML==6.0.1 PyYAML==6.0.1
paho-mqtt==1.6.1 paho-mqtt==1.6.1
colorama==0.4.6 colorama==0.4.6
@ -10,8 +10,8 @@ platformio==6.1.11 # When updating platformio, also update Dockerfile
esptool==4.6.2 esptool==4.6.2
click==8.1.7 click==8.1.7
esphome-dashboard==20231107.0 esphome-dashboard==20231107.0
aioesphomeapi==19.2.1 aioesphomeapi==19.3.0
zeroconf==0.127.0 zeroconf==0.128.0
python-magic==0.4.27 python-magic==0.4.27
# esp-idf requires this, but doesn't bundle it by default # esp-idf requires this, but doesn't bundle it by default

View file

@ -1,4 +1,4 @@
pylint==2.17.6 pylint==3.0.2
flake8==6.1.0 # also change in .pre-commit-config.yaml when updating flake8==6.1.0 # also change in .pre-commit-config.yaml when updating
black==23.11.0 # also change in .pre-commit-config.yaml when updating black==23.11.0 # also change in .pre-commit-config.yaml when updating
pyupgrade==3.15.0 # also change in .pre-commit-config.yaml when updating pyupgrade==3.15.0 # also change in .pre-commit-config.yaml when updating
@ -8,7 +8,7 @@ pre-commit
pytest==7.4.3 pytest==7.4.3
pytest-cov==4.1.0 pytest-cov==4.1.0
pytest-mock==3.12.0 pytest-mock==3.12.0
pytest-asyncio==0.21.1 pytest-asyncio==0.23.2
asyncmock==0.4.2 asyncmock==0.4.2
hypothesis==5.49.0 hypothesis==5.49.0

View file

@ -20,7 +20,7 @@ from esphome.const import (
CONF_WIFI, CONF_WIFI,
) )
from esphome.components.packages import do_packages_pass from esphome.components.packages import do_packages_pass
from esphome.config_helpers import Extend from esphome.config_helpers import Extend, Remove
import esphome.config_validation as cv import esphome.config_validation as cv
# Test strings # Test strings
@ -349,3 +349,165 @@ def test_package_merge_by_missing_id():
actual = do_packages_pass(config) actual = do_packages_pass(config)
assert actual == expected assert actual == expected
def test_package_list_remove_by_id():
"""
Ensures that components with matching IDs are removed correctly.
In this test, two sensors are defined in a package, and one of them is removed at the top level.
"""
config = {
CONF_PACKAGES: {
"package_sensors": {
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_1,
CONF_PLATFORM: TEST_SENSOR_PLATFORM_1,
CONF_NAME: TEST_SENSOR_NAME_1,
},
{
CONF_ID: TEST_SENSOR_ID_2,
CONF_PLATFORM: TEST_SENSOR_PLATFORM_1,
CONF_NAME: TEST_SENSOR_NAME_2,
},
]
},
# "package2": {
# CONF_SENSOR: [
# {
# CONF_ID: Remove(TEST_SENSOR_ID_1),
# }
# ],
# },
},
CONF_SENSOR: [
{
CONF_ID: Remove(TEST_SENSOR_ID_1),
},
],
}
expected = {
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_2,
CONF_PLATFORM: TEST_SENSOR_PLATFORM_1,
CONF_NAME: TEST_SENSOR_NAME_2,
},
]
}
actual = do_packages_pass(config)
assert actual == expected
def test_multiple_package_list_remove_by_id():
"""
Ensures that components with matching IDs are removed correctly.
In this test, two sensors are defined in a package, and one of them is removed in another package.
"""
config = {
CONF_PACKAGES: {
"package_sensors": {
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_1,
CONF_PLATFORM: TEST_SENSOR_PLATFORM_1,
CONF_NAME: TEST_SENSOR_NAME_1,
},
{
CONF_ID: TEST_SENSOR_ID_2,
CONF_PLATFORM: TEST_SENSOR_PLATFORM_1,
CONF_NAME: TEST_SENSOR_NAME_2,
},
]
},
"package2": {
CONF_SENSOR: [
{
CONF_ID: Remove(TEST_SENSOR_ID_1),
}
],
},
},
}
expected = {
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_2,
CONF_PLATFORM: TEST_SENSOR_PLATFORM_1,
CONF_NAME: TEST_SENSOR_NAME_2,
},
]
}
actual = do_packages_pass(config)
assert actual == expected
def test_package_dict_remove_by_id(basic_wifi, basic_esphome):
"""
Ensures that components with missing IDs are removed from dict.
"""
"""
Ensures that the top-level configuration takes precedence over duplicate keys defined in a package.
In this test, CONF_SSID should be overwritten by that defined in the top-level config.
"""
config = {
CONF_ESPHOME: basic_esphome,
CONF_PACKAGES: {"network": {CONF_WIFI: basic_wifi}},
CONF_WIFI: Remove(),
}
expected = {
CONF_ESPHOME: basic_esphome,
}
actual = do_packages_pass(config)
assert actual == expected
def test_package_remove_by_missing_id():
"""
Ensures that components with missing IDs are not merged.
"""
config = {
CONF_PACKAGES: {
"sensors": {
CONF_SENSOR: [
{CONF_ID: TEST_SENSOR_ID_1, CONF_FILTERS: [{CONF_MULTIPLY: 42.0}]},
]
}
},
"missing_key": Remove(),
CONF_SENSOR: [
{CONF_ID: TEST_SENSOR_ID_1, CONF_FILTERS: [{CONF_MULTIPLY: 10.0}]},
{CONF_ID: Remove(TEST_SENSOR_ID_2), CONF_FILTERS: [{CONF_OFFSET: 146.0}]},
],
}
expected = {
"missing_key": Remove(),
CONF_SENSOR: [
{
CONF_ID: TEST_SENSOR_ID_1,
CONF_FILTERS: [{CONF_MULTIPLY: 42.0}],
},
{
CONF_ID: TEST_SENSOR_ID_1,
CONF_FILTERS: [{CONF_MULTIPLY: 10.0}],
},
{
CONF_ID: Remove(TEST_SENSOR_ID_2),
CONF_FILTERS: [{CONF_OFFSET: 146.0}],
},
],
}
actual = do_packages_pass(config)
assert actual == expected

View file

@ -0,0 +1,6 @@
import pathlib
def get_fixture_path(filename: str) -> pathlib.Path:
"""Get path of fixture."""
return pathlib.Path(__file__).parent.joinpath("fixtures", filename)

View file

@ -0,0 +1,47 @@
substitutions:
name: picoproxy
friendly_name: Pico Proxy
esphome:
name: ${name}
friendly_name: ${friendly_name}
project:
name: esphome.bluetooth-proxy
version: "1.0"
esp32:
board: esp32dev
framework:
type: esp-idf
wifi:
ap:
api:
logger:
ota:
improv_serial:
dashboard_import:
package_import_url: github://esphome/firmware/bluetooth-proxy/esp32-generic.yaml@main
button:
- platform: factory_reset
id: resetf
- platform: safe_mode
name: Safe Mode Boot
entity_category: diagnostic
sensor:
- platform: template
id: pm11
name: "pm 1.0µm"
lambda: return 1.0;
- platform: template
id: pm251
name: "pm 2.5µm"
lambda: return 2.5;
- platform: template
id: pm101
name: "pm 10µm"
lambda: return 10;

View file

@ -0,0 +1,80 @@
from __future__ import annotations
import asyncio
import json
import os
from unittest.mock import Mock
import pytest
import pytest_asyncio
from tornado.httpclient import AsyncHTTPClient, HTTPResponse
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.testing import bind_unused_port
from esphome.dashboard import web_server
from esphome.dashboard.core import DASHBOARD
from .common import get_fixture_path
class DashboardTestHelper:
def __init__(self, io_loop: IOLoop, client: AsyncHTTPClient, port: int) -> None:
self.io_loop = io_loop
self.client = client
self.port = port
async def fetch(self, path: str, **kwargs) -> HTTPResponse:
"""Get a response for the given path."""
if path.lower().startswith(("http://", "https://")):
url = path
else:
url = f"http://127.0.0.1:{self.port}{path}"
future = self.client.fetch(url, raise_error=True, **kwargs)
result = await future
return result
@pytest_asyncio.fixture()
async def dashboard() -> DashboardTestHelper:
sock, port = bind_unused_port()
args = Mock(
ha_addon=True,
configuration=get_fixture_path("conf"),
port=port,
)
DASHBOARD.settings.parse_args(args)
app = web_server.make_app()
http_server = HTTPServer(app)
http_server.add_sockets([sock])
await DASHBOARD.async_setup()
os.environ["DISABLE_HA_AUTHENTICATION"] = "1"
assert DASHBOARD.settings.using_password is False
assert DASHBOARD.settings.on_ha_addon is True
assert DASHBOARD.settings.using_auth is False
task = asyncio.create_task(DASHBOARD.async_run())
client = AsyncHTTPClient()
io_loop = IOLoop(make_current=False)
yield DashboardTestHelper(io_loop, client, port)
task.cancel()
sock.close()
client.close()
io_loop.close()
@pytest.mark.asyncio
async def test_main_page(dashboard: DashboardTestHelper) -> None:
response = await dashboard.fetch("/")
assert response.code == 200
@pytest.mark.asyncio
async def test_devices_page(dashboard: DashboardTestHelper) -> None:
response = await dashboard.fetch("/devices")
assert response.code == 200
assert response.headers["content-type"] == "application/json"
json_data = json.loads(response.body.decode())
configured_devices = json_data["configured"]
first_device = configured_devices[0]
assert first_device["name"] == "pico"
assert first_device["configuration"] == "pico.yaml"

View file

@ -54,7 +54,9 @@ power_supply:
i2c: i2c:
sda: 21 sda: 21
scl: 22 scl:
number: 22
allow_other_uses: true
scan: true scan: true
frequency: 100kHz frequency: 100kHz
setup_priority: -100 setup_priority: -100
@ -86,7 +88,9 @@ light:
- platform: fastled_clockless - platform: fastled_clockless
id: addr1 id: addr1
chipset: WS2811 chipset: WS2811
pin: GPIO23 pin:
allow_other_uses: true
number: GPIO23
num_leds: 60 num_leds: 60
rgb_order: BRG rgb_order: BRG
max_refresh_rate: 20ms max_refresh_rate: 20ms
@ -168,8 +172,12 @@ light:
- platform: fastled_spi - platform: fastled_spi
id: addr2 id: addr2
chipset: WS2801 chipset: WS2801
data_pin: GPIO23 data_pin:
clock_pin: GPIO22 allow_other_uses: true
number: GPIO23
clock_pin:
number: GPIO22
allow_other_uses: true
data_rate: 2MHz data_rate: 2MHz
num_leds: 60 num_leds: 60
rgb_order: BRG rgb_order: BRG
@ -190,7 +198,9 @@ light:
variant: SK6812 variant: SK6812
method: ESP32_I2S_0 method: ESP32_I2S_0
num_leds: 60 num_leds: 60
pin: GPIO23 pin:
allow_other_uses: true
number: GPIO23
- platform: partition - platform: partition
name: Partition Light name: Partition Light
segments: segments:

View file

@ -181,8 +181,12 @@ mqtt:
- light.turn_off: ${roomname}_lights - light.turn_off: ${roomname}_lights
i2c: i2c:
sda: 21 sda:
scl: 22 allow_other_uses: true
number: 21
scl:
allow_other_uses: true
number: 22
scan: true scan: true
frequency: 100kHz frequency: 100kHz
setup_priority: -100 setup_priority: -100
@ -190,15 +194,23 @@ i2c:
spi: spi:
id: spi_bus id: spi_bus
clk_pin: GPIO21 clk_pin:
mosi_pin: GPIO22 allow_other_uses: true
miso_pin: GPIO23 number: GPIO21
mosi_pin:
allow_other_uses: true
number: GPIO22
miso_pin:
allow_other_uses: true
number: GPIO23
uart: uart:
- tx_pin: - tx_pin:
allow_other_uses: true
number: GPIO22 number: GPIO22
inverted: true inverted: true
rx_pin: rx_pin:
allow_other_uses: true
number: GPIO23 number: GPIO23
inverted: true inverted: true
baud_rate: 115200 baud_rate: 115200
@ -220,18 +232,30 @@ uart:
- lambda: UARTDebug::log_int(direction, bytes, ','); - lambda: UARTDebug::log_int(direction, bytes, ',');
- lambda: UARTDebug::log_binary(direction, bytes, ';'); - lambda: UARTDebug::log_binary(direction, bytes, ';');
- id: ld2410_uart - id: ld2410_uart
tx_pin: 18 tx_pin:
rx_pin: 23 allow_other_uses: true
number: 18
rx_pin:
allow_other_uses: true
number: 23
baud_rate: 256000 baud_rate: 256000
parity: NONE parity: NONE
stop_bits: 1 stop_bits: 1
- id: dfrobot_mmwave_uart - id: dfrobot_mmwave_uart
tx_pin: 14 tx_pin:
rx_pin: 27 allow_other_uses: true
number: 14
rx_pin:
allow_other_uses: true
number: 27
baud_rate: 115200 baud_rate: 115200
- id: ld2420_uart - id: ld2420_uart
tx_pin: 17 tx_pin:
rx_pin: 16 allow_other_uses: true
number: 17
rx_pin:
allow_other_uses: true
number: 16
baud_rate: 115200 baud_rate: 115200
parity: NONE parity: NONE
stop_bits: 1 stop_bits: 1
@ -282,12 +306,16 @@ power_supply:
keep_on_time: 10s keep_on_time: 10s
pin: pin:
number: 13 number: 13
allow_other_uses: true
inverted: true inverted: true
deep_sleep: deep_sleep:
run_duration: 20s run_duration: 20s
sleep_duration: 50s sleep_duration: 50s
wakeup_pin: GPIO2 wakeup_pin:
allow_other_uses: true
number: GPIO2
ignore_strapping_warning: true
wakeup_pin_mode: INVERT_WAKEUP wakeup_pin_mode: INVERT_WAKEUP
ads1115: ads1115:
@ -295,11 +323,18 @@ ads1115:
i2c_id: i2c_bus i2c_id: i2c_bus
dallas: dallas:
pin: GPIO23 pin:
allow_other_uses: true
number: GPIO23
as3935_spi: as3935_spi:
cs_pin: GPIO12 cs_pin:
irq_pin: GPIO13 ignore_strapping_warning: true
allow_other_uses: true
number: GPIO12
irq_pin:
allow_other_uses: true
number: GPIO13
esp32_ble: esp32_ble:
io_capability: keyboard_only io_capability: keyboard_only
@ -339,16 +374,24 @@ bedjet:
time_id: sntp_time time_id: sntp_time
mcp23s08: mcp23s08:
- id: mcp23s08_hub - id: mcp23s08_hub
cs_pin: GPIO12 cs_pin:
ignore_strapping_warning: true
number: GPIO12
allow_other_uses: true
deviceaddress: 0 deviceaddress: 0
mcp23s17: mcp23s17:
- id: mcp23s17_hub - id: mcp23s17_hub
cs_pin: GPIO12 cs_pin:
ignore_strapping_warning: true
number: GPIO12
allow_other_uses: true
deviceaddress: 1 deviceaddress: 1
micronova: micronova:
enable_rx_pin: 4 enable_rx_pin:
allow_other_uses: true
number: 4
uart_id: uart_0 uart_id: uart_0
dfrobot_sen0395: dfrobot_sen0395:
@ -539,7 +582,9 @@ sensor:
name: NIR name: NIR
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: atm90e26 - platform: atm90e26
cs_pin: 5 cs_pin:
allow_other_uses: true
number: 5
voltage: voltage:
name: Line Voltage name: Line Voltage
current: current:
@ -558,7 +603,9 @@ sensor:
gain_voltage: 26400 gain_voltage: 26400
gain_ct: 31251 gain_ct: 31251
- platform: atm90e32 - platform: atm90e32
cs_pin: 5 cs_pin:
allow_other_uses: true
number: 5
phase_a: phase_a:
voltage: voltage:
name: EMON Line Voltage A name: EMON Line Voltage A
@ -675,7 +722,9 @@ sensor:
index: 1 index: 1
name: Living Room Temperature 2 name: Living Room Temperature 2
- platform: dht - platform: dht
pin: GPIO26 pin:
allow_other_uses: true
number: GPIO26
temperature: temperature:
id: dht_temperature id: dht_temperature
name: Living Room Temperature 3 name: Living Room Temperature 3
@ -692,7 +741,9 @@ sensor:
update_interval: 15s update_interval: 15s
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: duty_cycle - platform: duty_cycle
pin: GPIO25 pin:
allow_other_uses: true
number: GPIO25
name: Duty Cycle Sensor name: Duty Cycle Sensor
- platform: ee895 - platform: ee895
co2: co2:
@ -721,9 +772,15 @@ sensor:
update_interval: 15s update_interval: 15s
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: hlw8012 - platform: hlw8012
sel_pin: 5 sel_pin:
cf_pin: 14 allow_other_uses: true
cf1_pin: 13 number: 5
cf_pin:
allow_other_uses: true
number: 14
cf1_pin:
allow_other_uses: true
number: 13
current: current:
name: HLW8012 Current name: HLW8012 Current
voltage: voltage:
@ -772,7 +829,9 @@ sensor:
max_pressure: 15 max_pressure: 15
temperature: temperature:
name: Honeywell temperature name: Honeywell temperature
cs_pin: GPIO5 cs_pin:
allow_other_uses: true
number: GPIO5
- platform: honeywellabp2_i2c - platform: honeywellabp2_i2c
pressure: pressure:
name: Honeywell2 pressure name: Honeywell2 pressure
@ -806,8 +865,12 @@ sensor:
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: hx711 - platform: hx711
name: HX711 Value name: HX711 Value
dout_pin: GPIO23 dout_pin:
clk_pin: GPIO25 allow_other_uses: true
number: GPIO23
clk_pin:
allow_other_uses: true
number: GPIO25
gain: 128 gain: 128
update_interval: 15s update_interval: 15s
- platform: ina219 - platform: ina219
@ -880,22 +943,30 @@ sensor:
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: max6675 - platform: max6675
name: Living Room Temperature name: Living Room Temperature
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
update_interval: 15s update_interval: 15s
- platform: max31855 - platform: max31855
name: Den Temperature name: Den Temperature
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
update_interval: 15s update_interval: 15s
reference_temperature: reference_temperature:
name: MAX31855 Internal Temperature name: MAX31855 Internal Temperature
- platform: max31856 - platform: max31856
name: BBQ Temperature name: BBQ Temperature
cs_pin: GPIO17 cs_pin:
allow_other_uses: true
number: GPIO17
update_interval: 15s update_interval: 15s
mains_filter: 50Hz mains_filter: 50Hz
- platform: max31865 - platform: max31865
name: Water Tank Temperature name: Water Tank Temperature
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
update_interval: 15s update_interval: 15s
reference_resistance: 430 Ω reference_resistance: 430 Ω
rtd_nominal_resistance: 100 Ω rtd_nominal_resistance: 100 Ω
@ -1007,7 +1078,10 @@ sensor:
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: pulse_counter - platform: pulse_counter
name: Pulse Counter name: Pulse Counter
pin: GPIO12 pin:
ignore_strapping_warning: true
number: GPIO12
allow_other_uses: true
count_mode: count_mode:
rising_edge: INCREMENT rising_edge: INCREMENT
falling_edge: DECREMENT falling_edge: DECREMENT
@ -1016,7 +1090,10 @@ sensor:
- platform: pulse_meter - platform: pulse_meter
name: Pulse Meter name: Pulse Meter
id: pulse_meter_sensor id: pulse_meter_sensor
pin: GPIO12 pin:
ignore_strapping_warning: true
number: GPIO12
allow_other_uses: true
internal_filter: 100ms internal_filter: 100ms
timeout: 2 min timeout: 2 min
on_value: on_value:
@ -1039,9 +1116,15 @@ sensor:
- platform: rotary_encoder - platform: rotary_encoder
name: Rotary Encoder name: Rotary Encoder
id: rotary_encoder1 id: rotary_encoder1
pin_a: GPIO23 pin_a:
pin_b: GPIO25 allow_other_uses: true
pin_reset: GPIO25 number: GPIO23
pin_b:
allow_other_uses: true
number: GPIO25
pin_reset:
allow_other_uses: true
number: GPIO25
filters: filters:
- or: - or:
- debounce: 0.1s - debounce: 0.1s
@ -1064,7 +1147,9 @@ sensor:
- display_menu.up: - display_menu.up:
- platform: pulse_width - platform: pulse_width
name: Pulse Width name: Pulse Width
pin: GPIO12 pin:
allow_other_uses: true
number: GPIO12
- platform: sm300d2 - platform: sm300d2
uart_id: uart_0 uart_id: uart_0
co2: co2:
@ -1247,9 +1332,12 @@ sensor:
address: 0x48 address: 0x48
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: ultrasonic - platform: ultrasonic
trigger_pin: GPIO25 trigger_pin:
allow_other_uses: true
number: GPIO25
echo_pin: echo_pin:
number: GPIO23 number: GPIO23
allow_other_uses: true
inverted: true inverted: true
name: Ultrasonic Sensor name: Ultrasonic Sensor
timeout: 5.5m timeout: 5.5m
@ -1296,9 +1384,14 @@ sensor:
pin: pin:
number: GPIO04 number: GPIO04
mode: INPUT mode: INPUT
allow_other_uses: true
- platform: zyaura - platform: zyaura
clock_pin: GPIO5 clock_pin:
data_pin: GPIO4 allow_other_uses: true
number: GPIO5
data_pin:
allow_other_uses: true
number: GPIO4
co2: co2:
name: ZyAura CO2 name: ZyAura CO2
temperature: temperature:
@ -1572,6 +1665,7 @@ binary_sensor:
mcp23xxx: mcp23s08_hub mcp23xxx: mcp23s08_hub
# Use pin number 1 # Use pin number 1
number: 1 number: 1
allow_other_uses: true
# One of INPUT or INPUT_PULLUP # One of INPUT or INPUT_PULLUP
mode: INPUT_PULLUP mode: INPUT_PULLUP
inverted: false inverted: false
@ -1581,6 +1675,7 @@ binary_sensor:
mcp23xxx: mcp23s17_hub mcp23xxx: mcp23s17_hub
# Use pin number 1 # Use pin number 1
number: 1 number: 1
allow_other_uses: true
# One of INPUT or INPUT_PULLUP # One of INPUT or INPUT_PULLUP
mode: INPUT_PULLUP mode: INPUT_PULLUP
inverted: false inverted: false
@ -1589,13 +1684,16 @@ binary_sensor:
pin: pin:
mcp23xxx: mcp23s17_hub mcp23xxx: mcp23s17_hub
# Use pin number 1 # Use pin number 1
allow_other_uses: true
number: 1 number: 1
# One of INPUT or INPUT_PULLUP # One of INPUT or INPUT_PULLUP
mode: INPUT_PULLUP mode: INPUT_PULLUP
inverted: false inverted: false
interrupt: FALLING interrupt: FALLING
- platform: gpio - platform: gpio
pin: GPIO9 pin:
allow_other_uses: true
number: GPIO9
name: Living Room Window name: Living Room Window
device_class: window device_class: window
filters: filters:
@ -1664,11 +1762,13 @@ binary_sensor:
- platform: gpio - platform: gpio
pin: pin:
number: GPIO9 number: GPIO9
allow_other_uses: true
mode: INPUT_PULLUP mode: INPUT_PULLUP
name: Living Room Window 2 name: Living Room Window 2
- platform: gpio - platform: gpio
pin: pin:
number: GPIO9 number: GPIO9
allow_other_uses: true
mode: INPUT_OUTPUT_OPEN_DRAIN mode: INPUT_OUTPUT_OPEN_DRAIN
name: Living Room Button name: Living Room Button
- platform: status - platform: status
@ -1747,6 +1847,7 @@ binary_sensor:
pin: pin:
mcp23xxx: mcp23017_hub mcp23xxx: mcp23017_hub
number: 1 number: 1
allow_other_uses: true
mode: INPUT mode: INPUT
inverted: true inverted: true
- platform: gpio - platform: gpio
@ -1767,6 +1868,7 @@ binary_sensor:
name: Speed Fan Cycle binary sensor" name: Speed Fan Cycle binary sensor"
pin: pin:
number: 18 number: 18
allow_other_uses: true
mode: mode:
input: true input: true
pulldown: true pulldown: true
@ -1891,42 +1993,66 @@ tlc59208f:
i2c_id: i2c_bus i2c_id: i2c_bus
my9231: my9231:
data_pin: GPIO12 data_pin:
clock_pin: GPIO14 allow_other_uses: true
number: GPIO12
clock_pin:
allow_other_uses: true
number: GPIO14
num_channels: 6 num_channels: 6
num_chips: 2 num_chips: 2
bit_depth: 16 bit_depth: 16
sm2235: sm2235:
data_pin: GPIO4 data_pin:
clock_pin: GPIO5 allow_other_uses: true
number: GPIO4
clock_pin:
allow_other_uses: true
number: GPIO5
max_power_color_channels: 9 max_power_color_channels: 9
max_power_white_channels: 9 max_power_white_channels: 9
sm2335: sm2335:
data_pin: GPIO4 data_pin:
clock_pin: GPIO5 allow_other_uses: true
number: GPIO4
clock_pin:
allow_other_uses: true
number: GPIO5
max_power_color_channels: 9 max_power_color_channels: 9
max_power_white_channels: 9 max_power_white_channels: 9
bp1658cj: bp1658cj:
data_pin: GPIO3 data_pin:
clock_pin: GPIO5 allow_other_uses: true
number: GPIO3
clock_pin:
allow_other_uses: true
number: GPIO5
max_power_color_channels: 4 max_power_color_channels: 4
max_power_white_channels: 6 max_power_white_channels: 6
bp5758d: bp5758d:
data_pin: GPIO3 data_pin:
clock_pin: GPIO5 allow_other_uses: true
number: GPIO3
clock_pin:
allow_other_uses: true
number: GPIO5
output: output:
- platform: gpio - platform: gpio
pin: GPIO26 pin:
allow_other_uses: true
number: GPIO26
id: gpio_26 id: gpio_26
power_supply: atx_power_supply power_supply: atx_power_supply
inverted: false inverted: false
- platform: ledc - platform: ledc
pin: 19 pin:
allow_other_uses: true
number: 19
id: gpio_19 id: gpio_19
frequency: 1500Hz frequency: 1500Hz
channel: 14 channel: 14
@ -1996,6 +2122,7 @@ output:
pin: pin:
pcf8574: pcf8574_hub pcf8574: pcf8574_hub
number: 0 number: 0
#allow_other_uses: true
mode: OUTPUT mode: OUTPUT
inverted: false inverted: false
- platform: gpio - platform: gpio
@ -2003,6 +2130,7 @@ output:
pin: pin:
pca9554: pca9554_hub pca9554: pca9554_hub
number: 0 number: 0
#allow_other_uses: true
mode: OUTPUT mode: OUTPUT
inverted: false inverted: false
- platform: gpio - platform: gpio
@ -2010,6 +2138,7 @@ output:
pin: pin:
mcp23xxx: mcp23017_hub mcp23xxx: mcp23017_hub
number: 0 number: 0
allow_other_uses: true
mode: OUTPUT mode: OUTPUT
inverted: false inverted: false
- platform: gpio - platform: gpio
@ -2017,6 +2146,7 @@ output:
pin: pin:
mcp23xxx: mcp23008_hub mcp23xxx: mcp23008_hub
number: 0 number: 0
allow_other_uses: true
mode: OUTPUT mode: OUTPUT
inverted: false inverted: false
- platform: gpio - platform: gpio
@ -2076,14 +2206,22 @@ output:
channel: 3 channel: 3
- platform: slow_pwm - platform: slow_pwm
id: id24 id: id24
pin: GPIO26 pin:
allow_other_uses: true
number: GPIO26
period: 15s period: 15s
- platform: ac_dimmer - platform: ac_dimmer
id: dimmer1 id: dimmer1
gate_pin: GPIO5 gate_pin:
zero_cross_pin: GPIO26 allow_other_uses: true
number: GPIO5
zero_cross_pin:
allow_other_uses: true
number: GPIO26
- platform: esp32_dac - platform: esp32_dac
pin: GPIO25 pin:
allow_other_uses: true
number: GPIO25
id: dac_output id: dac_output
- platform: mcp4725 - platform: mcp4725
id: mcp4725_dac_output id: mcp4725_dac_output
@ -2147,9 +2285,15 @@ output:
current: 10 current: 10
- platform: x9c - platform: x9c
id: test_x9c id: test_x9c
cs_pin: GPIO25 cs_pin:
inc_pin: GPIO26 allow_other_uses: true
ud_pin: GPIO27 number: GPIO25
inc_pin:
allow_other_uses: true
number: GPIO26
ud_pin:
allow_other_uses: true
number: GPIO27
initial_value: 0.5 initial_value: 0.5
light: light:
@ -2256,7 +2400,9 @@ light:
warm_white_color_temperature: 500 mireds warm_white_color_temperature: 500 mireds
remote_transmitter: remote_transmitter:
- pin: 32 - pin:
allow_other_uses: true
number: 32
carrier_duty_percent: 100% carrier_duty_percent: 100%
climate: climate:
@ -2440,6 +2586,7 @@ switch:
mcp23xxx: mcp23s08_hub mcp23xxx: mcp23s08_hub
# Use pin number 0 # Use pin number 0
number: 0 number: 0
allow_other_uses: true
mode: OUTPUT mode: OUTPUT
inverted: false inverted: false
- platform: gpio - platform: gpio
@ -2448,10 +2595,13 @@ switch:
mcp23xxx: mcp23s17_hub mcp23xxx: mcp23s17_hub
# Use pin number 0 # Use pin number 0
number: 1 number: 1
allow_other_uses: true
mode: OUTPUT mode: OUTPUT
inverted: false inverted: false
- platform: gpio - platform: gpio
pin: GPIO25 pin:
allow_other_uses: true
number: GPIO25
name: Living Room Dehumidifier name: Living Room Dehumidifier
icon: "mdi:restart" icon: "mdi:restart"
inverted: true inverted: true
@ -2834,12 +2984,24 @@ display:
id: my_lcd_gpio id: my_lcd_gpio
dimensions: 18x4 dimensions: 18x4
data_pins: data_pins:
- GPIO19 -
- GPIO21 allow_other_uses: true
- GPIO22 number: GPIO19
- GPIO23 -
enable_pin: GPIO23 allow_other_uses: true
rs_pin: GPIO25 number: GPIO21
-
allow_other_uses: true
number: GPIO22
-
allow_other_uses: true
number: GPIO23
enable_pin:
allow_other_uses: true
number: GPIO23
rs_pin:
allow_other_uses: true
number: GPIO25
lambda: |- lambda: |-
it.print("Hello World!"); it.print("Hello World!");
- platform: lcd_pcf8574 - platform: lcd_pcf8574
@ -2860,13 +3022,19 @@ display:
it.print("Hello World!"); it.print("Hello World!");
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: max7219 - platform: max7219
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
num_chips: 1 num_chips: 1
lambda: |- lambda: |-
it.print("01234567"); it.print("01234567");
- platform: tm1637 - platform: tm1637
clk_pin: GPIO23 clk_pin:
dio_pin: GPIO25 allow_other_uses: true
number: GPIO23
dio_pin:
allow_other_uses: true
number: GPIO25
intensity: 3 intensity: 3
lambda: |- lambda: |-
it.print("1234"); it.print("1234");
@ -2874,6 +3042,7 @@ display:
clk_pin: clk_pin:
mcp23xxx: mcp23017_hub mcp23xxx: mcp23017_hub
number: 1 number: 1
allow_other_uses: true
dio_pin: dio_pin:
mcp23xxx: mcp23017_hub mcp23xxx: mcp23017_hub
number: 2 number: 2
@ -2883,15 +3052,23 @@ display:
lambda: |- lambda: |-
it.print("1234"); it.print("1234");
- platform: pcd8544 - platform: pcd8544
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
contrast: 60 contrast: 60
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ssd1306_i2c - platform: ssd1306_i2c
model: SSD1306_128X64 model: SSD1306_128X64
reset_pin: GPIO23 reset_pin:
allow_other_uses: true
number: GPIO23
address: 0x3C address: 0x3C
id: display1 id: display1
contrast: 60% contrast: 60%
@ -2912,28 +3089,48 @@ display:
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: ssd1306_spi - platform: ssd1306_spi
model: SSD1306 128x64 model: SSD1306 128x64
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ssd1322_spi - platform: ssd1322_spi
model: SSD1322 256x64 model: SSD1322 256x64
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ssd1325_spi - platform: ssd1325_spi
model: SSD1325 128x64 model: SSD1325 128x64
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ssd1327_i2c - platform: ssd1327_i2c
model: SSD1327 128X128 model: SSD1327 128X128
reset_pin: GPIO23 reset_pin:
allow_other_uses: true
number: GPIO23
address: 0x3D address: 0x3D
id: display1327 id: display1327
brightness: 60% brightness: 60%
@ -2947,29 +3144,53 @@ display:
i2c_id: i2c_bus i2c_id: i2c_bus
- platform: ssd1327_spi - platform: ssd1327_spi
model: SSD1327 128x128 model: SSD1327 128x128
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ssd1331_spi - platform: ssd1331_spi
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ssd1351_spi - platform: ssd1351_spi
model: SSD1351 128x128 model: SSD1351 128x128
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
reset_pin: GPIO23 number: GPIO23
dc_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: st7789v - platform: st7789v
model: TTGO TDisplay 135x240 model: TTGO TDisplay 135x240
cs_pin: GPIO5 cs_pin:
dc_pin: GPIO16 allow_other_uses: true
reset_pin: GPIO23 number: GPIO5
dc_pin:
allow_other_uses: true
number: GPIO16
reset_pin:
allow_other_uses: true
number: GPIO23
backlight_pin: no backlight_pin: no
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
@ -2977,15 +3198,22 @@ display:
width: 128 width: 128
height: 64 height: 64
cs_pin: cs_pin:
allow_other_uses: true
number: GPIO23 number: GPIO23
inverted: true inverted: true
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: st7735 - platform: st7735
model: INITR_BLACKTAB model: INITR_BLACKTAB
cs_pin: GPIO5 cs_pin:
dc_pin: GPIO16 allow_other_uses: true
reset_pin: GPIO23 number: GPIO5
dc_pin:
allow_other_uses: true
number: GPIO16
reset_pin:
allow_other_uses: true
number: GPIO23
rotation: 0 rotation: 0
device_width: 128 device_width: 128
device_height: 160 device_height: 160
@ -3001,10 +3229,16 @@ display:
mirror_x: true mirror_x: true
mirror_y: false mirror_y: false
model: TFT 2.4 model: TFT 2.4
cs_pin: GPIO5 cs_pin:
dc_pin: GPIO4 allow_other_uses: true
number: GPIO5
dc_pin:
allow_other_uses: true
number: GPIO4
color_palette: GRAYSCALE color_palette: GRAYSCALE
reset_pin: GPIO22 reset_pin:
allow_other_uses: true
number: GPIO22
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: ili9xxx - platform: ili9xxx
@ -3014,9 +3248,15 @@ display:
offset_width: 20 offset_width: 20
offset_height: 10 offset_height: 10
model: TFT 2.4 model: TFT 2.4
cs_pin: GPIO5 cs_pin:
dc_pin: GPIO4 allow_other_uses: true
reset_pin: GPIO22 number: GPIO5
dc_pin:
allow_other_uses: true
number: GPIO4
reset_pin:
allow_other_uses: true
number: GPIO22
auto_clear_enabled: false auto_clear_enabled: false
rotation: 90 rotation: 90
lambda: |- lambda: |-
@ -3041,10 +3281,18 @@ display:
it.print_battery(true); it.print_battery(true);
- platform: tm1621 - platform: tm1621
id: tm1621_display id: tm1621_display
cs_pin: GPIO17 cs_pin:
data_pin: GPIO5 allow_other_uses: true
read_pin: GPIO23 number: GPIO17
write_pin: GPIO18 data_pin:
allow_other_uses: true
number: GPIO5
read_pin:
allow_other_uses: true
number: GPIO23
write_pin:
allow_other_uses: true
number: GPIO18
lambda: |- lambda: |-
it.printf(0, "%.1f", id(dht_temperature).state); it.printf(0, "%.1f", id(dht_temperature).state);
it.display_celsius(true); it.display_celsius(true);
@ -3053,12 +3301,18 @@ display:
tm1651: tm1651:
id: tm1651_battery id: tm1651_battery
clk_pin: GPIO23 clk_pin:
dio_pin: GPIO23 allow_other_uses: true
number: GPIO23
dio_pin:
allow_other_uses: true
number: GPIO23
remote_receiver: remote_receiver:
id: rcvr id: rcvr
pin: GPIO32 pin:
allow_other_uses: true
number: GPIO32
dump: all dump: all
on_coolix: on_coolix:
then: then:
@ -3068,11 +3322,16 @@ remote_receiver:
delay: !lambda "return uint32_t(x.code) + x.protocol;" delay: !lambda "return uint32_t(x.code) + x.protocol;"
status_led: status_led:
pin: GPIO2 pin:
allow_other_uses: true
number: GPIO2
ignore_strapping_warning: true
pn532_spi: pn532_spi:
id: pn532_bs id: pn532_bs
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
update_interval: 1s update_interval: 1s
on_tag: on_tag:
- lambda: |- - lambda: |-
@ -3094,7 +3353,9 @@ rdm6300:
uart_id: uart_0 uart_id: uart_0
rc522_spi: rc522_spi:
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
update_interval: 1s update_interval: 1s
on_tag: on_tag:
- lambda: |- - lambda: |-
@ -3287,9 +3548,15 @@ mcp23016:
stepper: stepper:
- platform: a4988 - platform: a4988
id: my_stepper id: my_stepper
step_pin: GPIO23 step_pin:
dir_pin: GPIO25 allow_other_uses: true
sleep_pin: GPIO25 number: GPIO23
dir_pin:
allow_other_uses: true
number: GPIO25
sleep_pin:
allow_other_uses: true
number: GPIO25
max_speed: 250 steps/s max_speed: 250 steps/s
acceleration: 100 steps/s^2 acceleration: 100 steps/s^2
deceleration: 200 steps/s^2 deceleration: 200 steps/s^2
@ -3397,14 +3664,26 @@ text_sensor:
sn74hc595: sn74hc595:
- id: sn74hc595_hub - id: sn74hc595_hub
data_pin: GPIO21 data_pin:
clock_pin: GPIO23 allow_other_uses: true
latch_pin: GPIO22 number: GPIO21
oe_pin: GPIO32 clock_pin:
allow_other_uses: true
number: GPIO23
latch_pin:
allow_other_uses: true
number: GPIO22
oe_pin:
allow_other_uses: true
number: GPIO32
sr_count: 2 sr_count: 2
- id: sn74hc595_hub_2 - id: sn74hc595_hub_2
latch_pin: GPIO22 latch_pin:
oe_pin: GPIO32 allow_other_uses: true
number: GPIO22
oe_pin:
allow_other_uses: true
number: GPIO32
sr_count: 2 sr_count: 2
spi_id: spi_bus spi_id: spi_bus
@ -3456,8 +3735,12 @@ canbus:
} }
- platform: esp32_can - platform: esp32_can
id: esp32_internal_can id: esp32_internal_can
rx_pin: GPIO04 rx_pin:
tx_pin: GPIO05 allow_other_uses: true
number: GPIO04
tx_pin:
allow_other_uses: true
number: GPIO05
can_id: 4 can_id: 4
bit_rate: 50kbps bit_rate: 50kbps
on_frame: on_frame:

View file

@ -44,25 +44,42 @@ uart:
rx_pin: 3 rx_pin: 3
baud_rate: 9600 baud_rate: 9600
- id: uart_2 - id: uart_2
tx_pin: 17 tx_pin:
rx_pin: 16 allow_other_uses: true
number: 17
rx_pin:
allow_other_uses: true
number: 16
baud_rate: 19200 baud_rate: 19200
i2c: i2c:
sda:
number: 21
allow_other_uses: true
frequency: 100khz frequency: 100khz
spi: spi:
- id: spi_1 - id: spi_1
clk_pin: 12 clk_pin:
mosi_pin: 13 allow_other_uses: true
miso_pin: 14 number: 12
mosi_pin:
allow_other_uses: true
number: 13
miso_pin:
allow_other_uses: true
number: 14
- id: spi_2 - id: spi_2
clk_pin: 32 clk_pin:
allow_other_uses: true
number: 32
mosi_pin: 33 mosi_pin: 33
modbus: modbus:
uart_id: uart_1 uart_id: uart_1
flow_control_pin: 5 flow_control_pin:
allow_other_uses: true
number: 5
id: mod_bus1 id: mod_bus1
modbus_controller: modbus_controller:
@ -229,9 +246,15 @@ binary_sensor:
lambda: return x[0] & 1; lambda: return x[0] & 1;
tlc5947: tlc5947:
data_pin: GPIO12 data_pin:
clock_pin: GPIO14 allow_other_uses: true
lat_pin: GPIO15 number: GPIO12
clock_pin:
allow_other_uses: true
number: GPIO14
lat_pin:
allow_other_uses: true
number: GPIO15
gp8403: gp8403:
- id: gp8403_5v - id: gp8403_5v
@ -417,7 +440,9 @@ sensor:
- platform: adc - platform: adc
id: adc_sensor_p32 id: adc_sensor_p32
name: ADC pin 32 name: ADC pin 32
pin: 32 pin:
allow_other_uses: true
number: 32
attenuation: 11db attenuation: 11db
update_interval: 1s update_interval: 1s
- platform: internal_temperature - platform: internal_temperature
@ -584,7 +609,9 @@ sensor:
name: Kuntze temperature name: Kuntze temperature
- platform: ade7953_i2c - platform: ade7953_i2c
irq_pin: 16 irq_pin:
allow_other_uses: true
number: 16
voltage: voltage:
name: ADE7953 Voltage name: ADE7953 Voltage
current_a: current_a:
@ -612,7 +639,9 @@ sensor:
- platform: ade7953_spi - platform: ade7953_spi
spi_id: spi_1 spi_id: spi_1
cs_pin: 04 cs_pin: 04
irq_pin: 16 irq_pin:
allow_other_uses: true
number: 16
voltage: voltage:
name: ADE7953 Voltage name: ADE7953 Voltage
current_a: current_a:
@ -683,7 +712,9 @@ switch:
display: display:
- platform: tm1638 - platform: tm1638
id: primarydisplay id: primarydisplay
stb_pin: 5 #TM1638 STB stb_pin:
allow_other_uses: true
number: 5 #TM1638 STB
clk_pin: 18 #TM1638 CLK clk_pin: 18 #TM1638 CLK
dio_pin: 23 #TM1638 DIO dio_pin: 23 #TM1638 DIO
update_interval: 5s update_interval: 5s
@ -728,20 +759,32 @@ text_sensor:
sn74hc165: sn74hc165:
id: sn74hc165_hub id: sn74hc165_hub
data_pin: GPIO12 data_pin:
clock_pin: GPIO14 allow_other_uses: true
load_pin: GPIO27 number: GPIO12
clock_inhibit_pin: GPIO26 clock_pin:
allow_other_uses: true
number: GPIO14
load_pin:
number: GPIO27
clock_inhibit_pin:
number: GPIO26
sr_count: 4 sr_count: 4
matrix_keypad: matrix_keypad:
id: keypad id: keypad
rows: rows:
- pin: 21 - pin:
allow_other_uses: true
number: 21
- pin: 19 - pin: 19
columns: columns:
- pin: 17 - pin:
- pin: 16 allow_other_uses: true
number: 17
- pin:
allow_other_uses: true
number: 16
keys: "1234" keys: "1234"
key_collector: key_collector:
@ -753,14 +796,18 @@ key_collector:
light: light:
- platform: esp32_rmt_led_strip - platform: esp32_rmt_led_strip
id: led_strip id: led_strip
pin: 13 pin:
allow_other_uses: true
number: 13
num_leds: 60 num_leds: 60
rmt_channel: 6 rmt_channel: 6
rgb_order: GRB rgb_order: GRB
chipset: ws2812 chipset: ws2812
- platform: esp32_rmt_led_strip - platform: esp32_rmt_led_strip
id: led_strip2 id: led_strip2
pin: 15 pin:
allow_other_uses: true
number: 15
num_leds: 60 num_leds: 60
rmt_channel: 2 rmt_channel: 2
rgb_order: RGB rgb_order: RGB

View file

@ -17,11 +17,17 @@ substitutions:
ethernet: ethernet:
type: LAN8720 type: LAN8720
mdc_pin: GPIO23 mdc_pin:
mdio_pin: GPIO25 allow_other_uses: true
number: GPIO23
mdio_pin:
allow_other_uses: true
number: GPIO25
clk_mode: GPIO0_IN clk_mode: GPIO0_IN
phy_addr: 0 phy_addr: 0
power_pin: GPIO25 power_pin:
allow_other_uses: true
number: GPIO25
manual_ip: manual_ip:
static_ip: 192.168.178.56 static_ip: 192.168.178.56
gateway: 192.168.178.1 gateway: 192.168.178.1
@ -37,18 +43,32 @@ mdns:
api: api:
i2c: i2c:
sda: 21 sda:
scl: 22 allow_other_uses: true
number: 21
scl:
allow_other_uses: true
number: 22
scan: false scan: false
spi: spi:
clk_pin: GPIO21 clk_pin:
mosi_pin: GPIO22 allow_other_uses: true
miso_pin: GPIO23 number: GPIO21
mosi_pin:
allow_other_uses: true
number: GPIO22
miso_pin:
allow_other_uses: true
number: GPIO23
uart: uart:
tx_pin: GPIO22 tx_pin:
rx_pin: GPIO23 allow_other_uses: true
number: GPIO22
rx_pin:
allow_other_uses: true
number: GPIO23
baud_rate: 115200 baud_rate: 115200
# Specifically added for testing debug with no after: definition. # Specifically added for testing debug with no after: definition.
debug: debug:
@ -73,21 +93,29 @@ deep_sleep:
gpio_wakeup_reason: 10s gpio_wakeup_reason: 10s
touch_wakeup_reason: 15s touch_wakeup_reason: 15s
sleep_duration: 50s sleep_duration: 50s
wakeup_pin: GPIO2 wakeup_pin:
allow_other_uses: true
number: GPIO2
wakeup_pin_mode: INVERT_WAKEUP wakeup_pin_mode: INVERT_WAKEUP
as3935_i2c: as3935_i2c:
irq_pin: GPIO12 irq_pin:
allow_other_uses: true
number: GPIO12
mcp3008: mcp3008:
- id: mcp3008_hub - id: mcp3008_hub
cs_pin: GPIO12 cs_pin:
allow_other_uses: true
number: GPIO12
output: output:
- platform: ac_dimmer - platform: ac_dimmer
id: dimmer1 id: dimmer1
gate_pin: GPIO5 gate_pin: GPIO5
zero_cross_pin: GPIO12 zero_cross_pin:
allow_other_uses: true
number: GPIO12
sensor: sensor:
- platform: homeassistant - platform: homeassistant
@ -534,7 +562,9 @@ binary_sensor:
name: Mi Motion Sensor 2 Button name: Mi Motion Sensor 2 Button
- platform: gpio - platform: gpio
id: gpio_set_retry_test id: gpio_set_retry_test
pin: GPIO9 pin:
allow_other_uses: true
number: GPIO9
on_press: on_press:
then: then:
- lambda: |- - lambda: |-
@ -601,7 +631,9 @@ xiaomi_rtcgq02lm:
bindkey: "48403ebe2d385db8d0c187f81e62cb64" bindkey: "48403ebe2d385db8d0c187f81e62cb64"
status_led: status_led:
pin: GPIO2 pin:
allow_other_uses: true
number: GPIO2
text_sensor: text_sensor:
- platform: version - platform: version
@ -704,9 +736,13 @@ script:
stepper: stepper:
- platform: uln2003 - platform: uln2003
id: my_stepper id: my_stepper
pin_a: GPIO23 pin_a:
allow_other_uses: true
number: GPIO23
pin_b: GPIO27 pin_b: GPIO27
pin_c: GPIO25 pin_c:
allow_other_uses: true
number: GPIO25
pin_d: GPIO26 pin_d: GPIO26
sleep_when_done: false sleep_when_done: false
step_mode: HALF_STEP step_mode: HALF_STEP
@ -731,7 +767,9 @@ display:
offset_height: 35 offset_height: 35
offset_width: 0 offset_width: 0
dc_pin: GPIO13 dc_pin: GPIO13
reset_pin: GPIO9 reset_pin:
allow_other_uses: true
number: GPIO9
image: image:
- id: binary_image - id: binary_image

View file

@ -29,14 +29,24 @@ web_server:
version: 2 version: 2
i2c: i2c:
sda: 4 sda:
scl: 5 allow_other_uses: true
number: 4
scl:
allow_other_uses: true
number: 5
scan: false scan: false
spi: spi:
clk_pin: GPIO12 clk_pin:
mosi_pin: GPIO13 allow_other_uses: true
miso_pin: GPIO14 number: GPIO12
mosi_pin:
allow_other_uses: true
number: GPIO13
miso_pin:
allow_other_uses: true
number: GPIO14
ota: ota:
@ -52,7 +62,9 @@ sensor:
name: VL53L0x Distance name: VL53L0x Distance
address: 0x29 address: 0x29
update_interval: 60s update_interval: 60s
enable_pin: GPIO13 enable_pin:
allow_other_uses: true
number: GPIO13
timeout: 200us timeout: 200us
- platform: apds9960 - platform: apds9960
type: clear type: clear
@ -170,7 +182,9 @@ sensor:
name: Custom Sensor name: Custom Sensor
- platform: ade7953_i2c - platform: ade7953_i2c
irq_pin: GPIO16 irq_pin:
allow_other_uses: true
number: GPIO16
voltage: voltage:
name: ADE7953 Voltage name: ADE7953 Voltage
id: ade7953_voltage id: ade7953_voltage
@ -199,8 +213,12 @@ sensor:
update_interval: 1s update_interval: 1s
- platform: ade7953_spi - platform: ade7953_spi
cs_pin: GPIO04 cs_pin:
irq_pin: GPIO16 allow_other_uses: true
number: GPIO04
irq_pin:
allow_other_uses: true
number: GPIO16
voltage: voltage:
name: ADE7953 Voltage name: ADE7953 Voltage
current_a: current_a:
@ -360,8 +378,12 @@ text_sensor:
name: Custom Text Sensor name: Custom Text Sensor
sm2135: sm2135:
data_pin: GPIO12 data_pin:
clock_pin: GPIO14 allow_other_uses: true
number: GPIO12
clock_pin:
allow_other_uses: true
number: GPIO14
rgb_current: 20mA rgb_current: 20mA
cw_current: 60mA cw_current: 60mA
@ -379,6 +401,7 @@ switch:
pin: pin:
mcp23xxx: mcp23017_hub mcp23xxx: mcp23017_hub
number: 0 number: 0
allow_other_uses: true
mode: OUTPUT mode: OUTPUT
interlock: &interlock [gpio_switch1, gpio_switch2, gpio_switch3] interlock: &interlock [gpio_switch1, gpio_switch2, gpio_switch3]
- platform: gpio - platform: gpio
@ -386,11 +409,14 @@ switch:
pin: pin:
mcp23xxx: mcp23008_hub mcp23xxx: mcp23008_hub
number: 0 number: 0
allow_other_uses: true
mode: OUTPUT mode: OUTPUT
interlock: *interlock interlock: *interlock
- platform: gpio - platform: gpio
id: gpio_switch3 id: gpio_switch3
pin: GPIO1 pin:
allow_other_uses: true
number: GPIO1
interlock: *interlock interlock: *interlock
- platform: custom - platform: custom
lambda: |- lambda: |-
@ -440,10 +466,18 @@ custom_component:
stepper: stepper:
- platform: uln2003 - platform: uln2003
id: my_stepper id: my_stepper
pin_a: GPIO12 pin_a:
pin_b: GPIO13 allow_other_uses: true
pin_c: GPIO14 number: GPIO12
pin_d: GPIO15 pin_b:
allow_other_uses: true
number: GPIO13
pin_c:
allow_other_uses: true
number: GPIO14
pin_d:
allow_other_uses: true
number: GPIO15
sleep_when_done: false sleep_when_done: false
step_mode: HALF_STEP step_mode: HALF_STEP
max_speed: 250 steps/s max_speed: 250 steps/s
@ -451,8 +485,12 @@ stepper:
deceleration: inf deceleration: inf
- platform: a4988 - platform: a4988
id: my_stepper2 id: my_stepper2
step_pin: GPIO1 step_pin:
dir_pin: GPIO2 allow_other_uses: true
number: GPIO1
dir_pin:
allow_other_uses: true
number: GPIO2
max_speed: 0.1 steps/s max_speed: 0.1 steps/s
acceleration: 10 steps/s^2 acceleration: 10 steps/s^2
deceleration: 10 steps/s^2 deceleration: 10 steps/s^2
@ -556,11 +594,14 @@ cover:
output: output:
- platform: esp8266_pwm - platform: esp8266_pwm
id: out id: out
pin: D3 pin:
number: D3
frequency: 50Hz frequency: 50Hz
- platform: esp8266_pwm - platform: esp8266_pwm
id: out2 id: out2
pin: D4 pin:
allow_other_uses: true
number: D4
- platform: custom - platform: custom
type: binary type: binary
lambda: |- lambda: |-
@ -572,7 +613,9 @@ output:
- platform: sigma_delta_output - platform: sigma_delta_output
id: sddac id: sddac
update_interval: 60s update_interval: 60s
pin: D4 pin:
allow_other_uses: true
number: D4
turn_on_action: turn_on_action:
then: then:
- logger.log: "Turned on" - logger.log: "Turned on"
@ -593,7 +636,9 @@ output:
outputs: outputs:
- id: custom_float - id: custom_float
- platform: slow_pwm - platform: slow_pwm
pin: GPIO5 pin:
allow_other_uses: true
number: GPIO5
id: my_slow_pwm id: my_slow_pwm
period: 15s period: 15s
restart_cycle_on_state_change: false restart_cycle_on_state_change: false
@ -635,12 +680,18 @@ servo:
ttp229_lsf: ttp229_lsf:
ttp229_bsf: ttp229_bsf:
sdo_pin: D2 sdo_pin:
scl_pin: D1 allow_other_uses: true
number: D2
scl_pin:
allow_other_uses: true
number: D1
display: display:
- platform: max7219digit - platform: max7219digit
cs_pin: GPIO15 cs_pin:
allow_other_uses: true
number: GPIO15
num_chips: 4 num_chips: 4
rotate_chip: 0 rotate_chip: 0
intensity: 10 intensity: 10
@ -666,10 +717,20 @@ button:
name: Restart Button (Factory Default Settings) name: Restart Button (Factory Default Settings)
cd74hc4067: cd74hc4067:
pin_s0: GPIO12 pin_s0:
pin_s1: GPIO13 allow_other_uses: true
pin_s2: GPIO14 number: GPIO12
pin_s3: GPIO15 pin_s1:
allow_other_uses: true
number: GPIO13
pin_s2:
allow_other_uses: true
number: GPIO14
pin_s3:
allow_other_uses: true
number: GPIO15
adc128s102: adc128s102:
cs_pin: GPIO12 cs_pin:
allow_other_uses: true
number: GPIO12

View file

@ -223,55 +223,102 @@ uart:
tx_pin: tx_pin:
number: GPIO1 number: GPIO1
inverted: true inverted: true
rx_pin: GPIO3 allow_other_uses: true
rx_pin:
allow_other_uses: true
number: GPIO3
baud_rate: 115200 baud_rate: 115200
- id: uart_2 - id: uart_2
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_3 - id: uart_3
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 4800 baud_rate: 4800
- id: uart_4 - id: uart_4
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_5 - id: uart_5
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_6 - id: uart_6
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_7 - id: uart_7
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 38400 baud_rate: 38400
- id: uart_8 - id: uart_8
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 4800 baud_rate: 4800
parity: NONE parity: NONE
stop_bits: 2 stop_bits: 2
# Specifically added for testing debug with no options at all. # Specifically added for testing debug with no options at all.
debug: debug:
- id: uart_9 - id: uart_9
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_10 - id: uart_10
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_11 - id: uart_11
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
- id: uart_12 - id: uart_12
tx_pin: GPIO4 tx_pin:
rx_pin: GPIO5 allow_other_uses: true
number: GPIO4
rx_pin:
allow_other_uses: true
number: GPIO5
baud_rate: 9600 baud_rate: 9600
modbus: modbus:
@ -748,13 +795,19 @@ binary_sensor:
- platform: gpio - platform: gpio
id: bin1 id: bin1
pin: 1 pin:
allow_other_uses: true
number: 1
- platform: gpio - platform: gpio
id: bin2 id: bin2
pin: 2 pin:
allow_other_uses: true
number: 2
- platform: gpio - platform: gpio
id: bin3 id: bin3
pin: 3 pin:
allow_other_uses: true
number: 3
globals: globals:
- id: my_global_string - id: my_global_string
@ -762,11 +815,15 @@ globals:
initial_value: '""' initial_value: '""'
remote_receiver: remote_receiver:
pin: GPIO12 pin:
allow_other_uses: true
number: GPIO12
dump: [] dump: []
status_led: status_led:
pin: GPIO2 pin:
allow_other_uses: true
number: GPIO2
text_sensor: text_sensor:
- platform: daly_bms - platform: daly_bms
@ -819,13 +876,19 @@ script:
switch: switch:
- platform: gpio - platform: gpio
id: gpio_switch1 id: gpio_switch1
pin: 1 pin:
allow_other_uses: true
number: 1
- platform: gpio - platform: gpio
id: gpio_switch2 id: gpio_switch2
pin: 2 pin:
allow_other_uses: true
number: 2
- platform: gpio - platform: gpio
id: gpio_switch3 id: gpio_switch3
pin: 3 pin:
allow_other_uses: true
number: 3
- platform: nextion - platform: nextion
id: r0 id: r0
@ -1023,13 +1086,18 @@ sprinkler:
output: output:
- platform: esp8266_pwm - platform: esp8266_pwm
id: out id: out
pin: D3 pin:
number: D3
frequency: 50Hz frequency: 50Hz
- platform: esp8266_pwm - platform: esp8266_pwm
id: out2 id: out2
pin: D4 pin:
allow_other_uses: true
number: D4
- platform: slow_pwm - platform: slow_pwm
pin: GPIO5 pin:
allow_other_uses: true
number: GPIO5
id: my_slow_pwm id: my_slow_pwm
period: 15s period: 15s
restart_cycle_on_state_change: false restart_cycle_on_state_change: false
@ -1039,7 +1107,9 @@ e131:
light: light:
- platform: neopixelbus - platform: neopixelbus
name: Neopixelbus Light name: Neopixelbus Light
pin: GPIO1 pin:
allow_other_uses: true
number: GPIO1
type: GRBW type: GRBW
variant: SK6812 variant: SK6812
method: ESP8266_UART0 method: ESP8266_UART0
@ -1071,6 +1141,12 @@ light:
max_brightness: 500 max_brightness: 500
firmware: "51.6" firmware: "51.6"
uart_id: uart_11 uart_id: uart_11
nrst_pin:
number: 5
allow_other_uses: true
boot0_pin:
number: 4
allow_other_uses: true
sim800l: sim800l:
uart_id: uart_4 uart_id: uart_4
@ -1096,8 +1172,12 @@ dfplayer:
logger.log: Playback finished event logger.log: Playback finished event
tm1651: tm1651:
id: tm1651_battery id: tm1651_battery
clk_pin: D6 clk_pin:
dio_pin: D5 allow_other_uses: true
number: D6
dio_pin:
allow_other_uses: true
number: D5
rf_bridge: rf_bridge:
uart_id: uart_5 uart_id: uart_5
@ -1150,7 +1230,9 @@ display:
lambda: 'ESP_LOGD("display","Display shows new page %u", x);' lambda: 'ESP_LOGD("display","Display shows new page %u", x);'
fingerprint_grow: fingerprint_grow:
sensing_pin: 4 sensing_pin:
allow_other_uses: true
number: 4
password: 0x12FE37DC password: 0x12FE37DC
new_password: 0xA65B9840 new_password: 0xA65B9840
on_finger_scan_matched: on_finger_scan_matched:
@ -1184,7 +1266,9 @@ dsmr:
decryption_key: 00112233445566778899aabbccddeeff decryption_key: 00112233445566778899aabbccddeeff
uart_id: uart_6 uart_id: uart_6
max_telegram_length: 1000 max_telegram_length: 1000
request_pin: D5 request_pin:
allow_other_uses: true
number: D5
request_interval: 20s request_interval: 20s
receive_timeout: 100ms receive_timeout: 100ms
@ -1197,8 +1281,11 @@ qr_code:
value: https://esphome.io/index.html value: https://esphome.io/index.html
lightwaverf: lightwaverf:
read_pin: 13 read_pin:
write_pin: 14 number: 13
write_pin:
allow_other_uses: true
number: 14
alarm_control_panel: alarm_control_panel:
- platform: template - platform: template

View file

@ -10,11 +10,17 @@ substitutions:
ethernet: ethernet:
type: LAN8720 type: LAN8720
mdc_pin: GPIO23 mdc_pin:
mdio_pin: GPIO25 allow_other_uses: true
number: GPIO23
mdio_pin:
allow_other_uses: true
number: GPIO25
clk_mode: GPIO0_IN clk_mode: GPIO0_IN
phy_addr: 0 phy_addr: 0
power_pin: GPIO25 power_pin:
allow_other_uses: true
number: GPIO25
manual_ip: manual_ip:
static_ip: 192.168.178.56 static_ip: 192.168.178.56
gateway: 192.168.178.1 gateway: 192.168.178.1
@ -34,37 +40,60 @@ mqtt:
api: api:
i2c: i2c:
sda: 21 sda:
scl: 22 allow_other_uses: true
number: 21
scl:
allow_other_uses: true
number: 22
scan: false scan: false
spi: spi:
- id: spi_id_1 - id: spi_id_1
clk_pin: GPIO21 clk_pin:
mosi_pin: GPIO22 allow_other_uses: true
miso_pin: GPIO23 number: GPIO21
mosi_pin:
allow_other_uses: true
number: GPIO22
miso_pin:
allow_other_uses: true
number: GPIO23
interface: hardware interface: hardware
- id: spi_id_2 - id: spi_id_2
clk_pin: GPIO32 clk_pin:
mosi_pin: GPIO33 number: GPIO32
mosi_pin:
number: GPIO33
interface: hardware interface: hardware
uart: uart:
- id: uart115200 - id: uart115200
tx_pin: GPIO22 tx_pin:
rx_pin: GPIO23 allow_other_uses: true
number: GPIO22
rx_pin:
allow_other_uses: true
number: GPIO23
baud_rate: 115200 baud_rate: 115200
- id: uart9600 - id: uart9600
tx_pin: GPIO22 tx_pin:
rx_pin: GPIO23 allow_other_uses: true
number: GPIO25
rx_pin:
allow_other_uses: true
number: GPIO26
baud_rate: 9600 baud_rate: 9600
- id: uart_he60r - id: uart_he60r
tx_pin: 22 tx_pin:
rx_pin: 23 number: GPIO18
allow_other_uses: true
rx_pin:
number: GPIO36
allow_other_uses: true
baud_rate: 1200 baud_rate: 1200
parity: EVEN parity: EVEN
ota: ota:
safe_mode: true safe_mode: true
port: 3286 port: 3286
@ -89,8 +118,9 @@ tuya:
time_id: sntp_time time_id: sntp_time
uart_id: uart115200 uart_id: uart115200
status_pin: status_pin:
number: 14 number: GPIO5
inverted: true inverted: true
allow_other_uses: true
select: select:
- platform: tuya - platform: tuya
@ -117,7 +147,9 @@ sx1509:
mcp3204: mcp3204:
spi_id: spi_id_1 spi_id: spi_id_1
cs_pin: GPIO23 cs_pin:
allow_other_uses: true
number: GPIO23
dac7678: dac7678:
address: 0x4A address: 0x4A
@ -510,7 +542,9 @@ light:
id: led_matrix_32x8 id: led_matrix_32x8
name: led_matrix_32x8 name: led_matrix_32x8
chipset: WS2812B chipset: WS2812B
pin: GPIO15 pin:
allow_other_uses: true
number: GPIO15
num_leds: 256 num_leds: 256
rgb_order: GRB rgb_order: GRB
default_transition_length: 0s default_transition_length: 0s
@ -566,20 +600,36 @@ display:
- platform: waveshare_epaper - platform: waveshare_epaper
spi_id: spi_id_1 spi_id: spi_id_1
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
busy_pin: GPIO23 number: GPIO23
reset_pin: GPIO23 dc_pin:
allow_other_uses: true
number: GPIO23
busy_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
model: 2.13in-ttgo-b1 model: 2.13in-ttgo-b1
full_update_every: 30 full_update_every: 30
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: waveshare_epaper - platform: waveshare_epaper
spi_id: spi_id_1 spi_id: spi_id_1
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
busy_pin: GPIO23 number: GPIO23
reset_pin: GPIO23 dc_pin:
allow_other_uses: true
number: GPIO23
busy_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
model: 2.90in model: 2.90in
full_update_every: 30 full_update_every: 30
reset_duration: 200ms reset_duration: 200ms
@ -587,20 +637,36 @@ display:
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: waveshare_epaper - platform: waveshare_epaper
spi_id: spi_id_1 spi_id: spi_id_1
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
busy_pin: GPIO23 number: GPIO23
reset_pin: GPIO23 dc_pin:
allow_other_uses: true
number: GPIO23
busy_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
model: 2.90inv2 model: 2.90inv2
full_update_every: 30 full_update_every: 30
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
- platform: waveshare_epaper - platform: waveshare_epaper
spi_id: spi_id_1 spi_id: spi_id_1
cs_pin: GPIO23 cs_pin:
dc_pin: GPIO23 allow_other_uses: true
busy_pin: GPIO23 number: GPIO23
reset_pin: GPIO23 dc_pin:
allow_other_uses: true
number: GPIO23
busy_pin:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO23
model: 1.54in-m5coreink-m09 model: 1.54in-m5coreink-m09
lambda: |- lambda: |-
it.rectangle(0, 0, it.get_width(), it.get_height()); it.rectangle(0, 0, it.get_width(), it.get_height());
@ -610,15 +676,54 @@ display:
partial_updating: false partial_updating: false
update_interval: 60s update_interval: 60s
ckv_pin: GPIO1 display_data_1_pin:
sph_pin: GPIO1 number: 5
gmod_pin: GPIO1 allow_other_uses: true
gpio0_enable_pin: GPIO1 display_data_2_pin:
oe_pin: GPIO1 number: 18
spv_pin: GPIO1 allow_other_uses: true
powerup_pin: GPIO1 display_data_3_pin:
wakeup_pin: GPIO1 number: 19
vcom_pin: GPIO1 allow_other_uses: true
display_data_5_pin:
number: 25
allow_other_uses: true
display_data_4_pin:
number: 23
allow_other_uses: true
display_data_6_pin:
number: 26
allow_other_uses: true
display_data_7_pin:
number: 27
allow_other_uses: true
ckv_pin:
allow_other_uses: true
number: GPIO1
sph_pin:
allow_other_uses: true
number: GPIO1
gmod_pin:
allow_other_uses: true
number: GPIO1
gpio0_enable_pin:
allow_other_uses: true
number: GPIO1
oe_pin:
allow_other_uses: true
number: GPIO1
spv_pin:
allow_other_uses: true
number: GPIO1
powerup_pin:
allow_other_uses: true
number: GPIO1
wakeup_pin:
allow_other_uses: true
number: GPIO1
vcom_pin:
allow_other_uses: true
number: GPIO1
number: number:
- platform: tuya - platform: tuya
@ -706,18 +811,54 @@ output:
id: dac7678_1_ch7 id: dac7678_1_ch7
esp32_camera: esp32_camera:
name: ESP-32 Camera name: ESP-32 Camera
data_pins: [GPIO17, GPIO35, GPIO34, GPIO5, GPIO39, GPIO18, GPIO36, GPIO19] data_pins:
vsync_pin: GPIO22 - number: GPIO17
href_pin: GPIO26 allow_other_uses: true
pixel_clock_pin: GPIO21 - number: GPIO35
allow_other_uses: true
-
number: GPIO34
-
number: GPIO5
allow_other_uses: true
-
number: GPIO39
-
number: GPIO18
allow_other_uses: true
-
number: GPIO36
allow_other_uses: true
-
number: GPIO19
allow_other_uses: true
vsync_pin:
allow_other_uses: true
number: GPIO22
href_pin:
allow_other_uses: true
number: GPIO26
pixel_clock_pin:
allow_other_uses: true
number: GPIO21
external_clock: external_clock:
pin: GPIO27 pin:
allow_other_uses: true
number: GPIO27
frequency: 20MHz frequency: 20MHz
i2c_pins: i2c_pins:
sda: GPIO25 sda:
scl: GPIO23 allow_other_uses: true
reset_pin: GPIO15 number: GPIO25
power_down_pin: GPIO1 scl:
allow_other_uses: true
number: GPIO23
reset_pin:
allow_other_uses: true
number: GPIO15
power_down_pin:
allow_other_uses: true
number: GPIO1
resolution: 640x480 resolution: 640x480
jpeg_quality: 10 jpeg_quality: 10
@ -748,8 +889,12 @@ button:
touchscreen: touchscreen:
- platform: ektf2232 - platform: ektf2232
interrupt_pin: GPIO36 interrupt_pin:
rts_pin: GPIO5 allow_other_uses: true
number: GPIO36
rts_pin:
allow_other_uses: true
number: GPIO5
display: inkplate_display display: inkplate_display
on_touch: on_touch:
- logger.log: - logger.log:
@ -759,8 +904,11 @@ touchscreen:
- platform: xpt2046 - platform: xpt2046
id: xpt_touchscreen id: xpt_touchscreen
spi_id: spi_id_2 spi_id: spi_id_2
cs_pin: 17 cs_pin:
interrupt_pin: 16 allow_other_uses: true
number: 17
interrupt_pin:
number: 16
display: inkplate_display display: inkplate_display
update_interval: 50ms update_interval: 50ms
report_interval: 1s report_interval: 1s
@ -777,7 +925,9 @@ touchscreen:
- platform: lilygo_t5_47 - platform: lilygo_t5_47
id: lilygo_touchscreen id: lilygo_touchscreen
interrupt_pin: GPIO36 interrupt_pin:
allow_other_uses: true
number: GPIO36
display: inkplate_display display: inkplate_display
on_touch: on_touch:
- logger.log: - logger.log:
@ -789,16 +939,25 @@ touchscreen:
i2s_audio: i2s_audio:
i2s_lrclk_pin: GPIO26 i2s_lrclk_pin:
i2s_bclk_pin: GPIO27 allow_other_uses: true
i2s_mclk_pin: GPIO25 number: GPIO26
i2s_bclk_pin:
allow_other_uses: true
number: GPIO27
i2s_mclk_pin:
allow_other_uses: true
number: GPIO25
media_player: media_player:
- platform: i2s_audio - platform: i2s_audio
name: None name: None
dac_type: external dac_type: external
i2s_dout_pin: GPIO25 i2s_dout_pin:
mute_pin: GPIO14 allow_other_uses: true
number: GPIO25
mute_pin:
number: GPIO14
on_state: on_state:
- media_player.play: - media_player.play:
- media_player.play_media: http://localhost/media.mp3 - media_player.play_media: http://localhost/media.mp3
@ -827,12 +986,16 @@ prometheus:
microphone: microphone:
- platform: i2s_audio - platform: i2s_audio
id: mic_id_adc id: mic_id_adc
adc_pin: GPIO35 adc_pin:
allow_other_uses: true
number: GPIO35
adc_type: internal adc_type: internal
- platform: i2s_audio - platform: i2s_audio
id: mic_id_external id: mic_id_external
i2s_din_pin: GPIO23 i2s_din_pin:
allow_other_uses: true
number: GPIO23
adc_type: external adc_type: external
pdm: false pdm: false
@ -840,7 +1003,9 @@ speaker:
- platform: i2s_audio - platform: i2s_audio
id: speaker_id id: speaker_id
dac_type: external dac_type: external
i2s_dout_pin: GPIO25 i2s_dout_pin:
allow_other_uses: true
number: GPIO25
mode: mono mode: mono
voice_assistant: voice_assistant:

View file

@ -42,17 +42,27 @@ uart:
baud_rate: 9600 baud_rate: 9600
- id: uart_2 - id: uart_2
tx_pin: tx_pin:
allow_other_uses: true
number: 17 number: 17
inverted: true inverted: true
rx_pin: 16 rx_pin:
allow_other_uses: true
number: 16
baud_rate: 19200 baud_rate: 19200
i2c: i2c:
sda:
allow_other_uses: true
number: 21
scl:
number: 22
frequency: 100khz frequency: 100khz
modbus: modbus:
uart_id: uart_1 uart_id: uart_1
flow_control_pin: 5 flow_control_pin:
allow_other_uses: true
number: 5
id: mod_bus1 id: mod_bus1
modbus_controller: modbus_controller:
@ -214,9 +224,15 @@ binary_sensor:
lambda: return x[0] & 1; lambda: return x[0] & 1;
tlc5947: tlc5947:
data_pin: GPIO12 data_pin:
clock_pin: GPIO14 number: GPIO12
lat_pin: GPIO15 allow_other_uses: true
clock_pin:
allow_other_uses: true
number: GPIO14
lat_pin:
allow_other_uses: true
number: GPIO15
gp8403: gp8403:
- id: gp8403_5v - id: gp8403_5v
@ -614,7 +630,9 @@ switch:
display: display:
- platform: tm1638 - platform: tm1638
id: primarydisplay id: primarydisplay
stb_pin: 5 #TM1638 STB stb_pin:
allow_other_uses: true
number: 5 #TM1638 STB
clk_pin: 18 #TM1638 CLK clk_pin: 18 #TM1638 CLK
dio_pin: 23 #TM1638 DIO dio_pin: 23 #TM1638 DIO
update_interval: 5s update_interval: 5s
@ -659,8 +677,12 @@ text_sensor:
sn74hc165: sn74hc165:
id: sn74hc165_hub id: sn74hc165_hub
data_pin: GPIO12 data_pin:
clock_pin: GPIO14 allow_other_uses: true
number: GPIO12
clock_pin:
allow_other_uses: true
number: GPIO14
load_pin: GPIO27 load_pin: GPIO27
clock_inhibit_pin: GPIO26 clock_inhibit_pin: GPIO26
sr_count: 4 sr_count: 4
@ -668,11 +690,17 @@ sn74hc165:
matrix_keypad: matrix_keypad:
id: keypad id: keypad
rows: rows:
- pin: 21 - pin:
allow_other_uses: true
number: 21
- pin: 19 - pin: 19
columns: columns:
- pin: 17 - pin:
- pin: 16 allow_other_uses: true
number: 17
- pin:
allow_other_uses: true
number: 16
keys: "1234" keys: "1234"
has_pulldowns: true has_pulldowns: true
@ -692,7 +720,9 @@ light:
chipset: ws2812 chipset: ws2812
- platform: esp32_rmt_led_strip - platform: esp32_rmt_led_strip
id: led_strip2 id: led_strip2
pin: 15 pin:
allow_other_uses: true
number: 15
num_leds: 60 num_leds: 60
rmt_channel: 2 rmt_channel: 2
rgb_order: RGB rgb_order: RGB

View file

@ -57,7 +57,9 @@ display:
model: ili9342 model: ili9342
cs_pin: GPIO5 cs_pin: GPIO5
dc_pin: GPIO4 dc_pin: GPIO4
reset_pin: GPIO48 reset_pin:
number: GPIO48
allow_other_uses: true
i2c: i2c:
scl: GPIO18 scl: GPIO18
@ -68,7 +70,10 @@ touchscreen:
interrupt_pin: interrupt_pin:
number: GPIO3 number: GPIO3
ignore_strapping_warning: true ignore_strapping_warning: true
reset_pin: GPIO48 allow_other_uses: false
reset_pin:
number: GPIO48
allow_other_uses: true
binary_sensor: binary_sensor:
- platform: tt21100 - platform: tt21100