mirror of
https://github.com/esphome/esphome.git
synced 2026-10-25 23:42:15 +00:00
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
479500a68d | ||
|
|
030d39f2cf | ||
|
|
f55a3dbf76 | ||
|
|
3500ecc1c1 | ||
|
|
8e4592fa87 | ||
|
|
76addfec20 | ||
|
|
c7073b9a0b | ||
|
|
480577e2f4 | ||
|
|
3808c767fd | ||
|
|
d6a9292c41 | ||
|
|
e38ee35cd8 | ||
|
|
81fecf2106 | ||
|
|
76e5b07416 |
No files matched your search
+13
-30
@@ -7,7 +7,6 @@ import re
|
||||
import textwrap
|
||||
|
||||
from esphome.build_helpers import pch
|
||||
from esphome.build_helpers.ccache import CCACHE_PCH_MIN_VERSION
|
||||
from esphome.components.esp32 import (
|
||||
KEY_SRC_CMAKE,
|
||||
get_esp32_variant,
|
||||
@@ -516,7 +515,7 @@ target_link_options(${{COMPONENT_LIB}} PUBLIC
|
||||
# Where CMake puts the .gch of the src component; ccache reads the checksum
|
||||
# next to it in place of the .gch
|
||||
_PCH_SUM_PATH = "build/esp-idf/src/CMakeFiles/__idf_src.dir/cmake_pch.hxx.gch.sum"
|
||||
# Where the CMake gate records its choice
|
||||
# Where the Windows gate records its choice
|
||||
_PCH_CHOICE_VAR = "ESPHOME_PCH"
|
||||
|
||||
|
||||
@@ -532,32 +531,16 @@ def _pch_cmake_block() -> str:
|
||||
block = f"""target_precompile_headers(${{COMPONENT_LIB}} PRIVATE
|
||||
{headers}
|
||||
)"""
|
||||
if pch.pch_forced():
|
||||
if not pch.pch_needs_gcc_check():
|
||||
return f"\n# ESPHome precompiled header\n{block}\n"
|
||||
# Only CMake knows the compiler version before the first configure, and
|
||||
# the ccache IDF found is the one the build runs
|
||||
gcc_gate = ""
|
||||
if pch.pch_needs_gcc_check():
|
||||
gcc_gate = f"""if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND ({pch.PCH_WINDOWS_CMAKE_OLD_GCC}))
|
||||
message(STATUS "ESPHome: GCC ${{CMAKE_CXX_COMPILER_VERSION}} cannot load a precompiled header on Windows; compiling without it")
|
||||
set(_esphome_pch OFF)
|
||||
endif()
|
||||
"""
|
||||
min_ccache = ".".join(map(str, CCACHE_PCH_MIN_VERSION))
|
||||
# Before the first configure only CMake knows the compiler version
|
||||
return f"""
|
||||
# ESPHome precompiled header, unless a check below rules it out
|
||||
set(_esphome_pch ON)
|
||||
{gcc_gate}if(CCACHE_ENABLE AND CCACHE_FOUND)
|
||||
execute_process(COMMAND "${{CCACHE_FOUND}}" --version OUTPUT_VARIABLE _esphome_ccache ERROR_QUIET)
|
||||
if(_esphome_ccache MATCHES "ccache version ([0-9.]+)")
|
||||
if(CMAKE_MATCH_1 VERSION_LESS {min_ccache})
|
||||
message(STATUS "ESPHome: ccache ${{CMAKE_MATCH_1}} can reuse stale objects with a precompiled header; compiling without it (upgrade ccache to {min_ccache} or newer, or set ESPHOME_PCH_ENABLE=1 to force)")
|
||||
set(_esphome_pch OFF)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set({_PCH_CHOICE_VAR} ${{_esphome_pch}} CACHE BOOL "ESPHome precompiled header in use" FORCE)
|
||||
if(_esphome_pch)
|
||||
# ESPHome precompiled header, unless GCC bug 14940 keeps it from loading
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND ({pch.PCH_WINDOWS_CMAKE_OLD_GCC}))
|
||||
message(STATUS "ESPHome: GCC ${{CMAKE_CXX_COMPILER_VERSION}} cannot load a precompiled header on Windows; compiling without it")
|
||||
set({_PCH_CHOICE_VAR} OFF CACHE BOOL "ESPHome precompiled header in use" FORCE)
|
||||
else()
|
||||
set({_PCH_CHOICE_VAR} ON CACHE BOOL "ESPHome precompiled header in use" FORCE)
|
||||
{textwrap.indent(block, " ")}
|
||||
endif()
|
||||
"""
|
||||
@@ -574,10 +557,10 @@ def write_pch_checksum() -> None:
|
||||
|
||||
if not pch.pch_enabled():
|
||||
return
|
||||
# Written whatever the gate chose last time: a build tree without that
|
||||
# choice, or a reconfigure that turns the pch on, must not see a stale sum
|
||||
if pch.pch_forced() or get_cmake_cache_value(_PCH_CHOICE_VAR) == "ON":
|
||||
pch.log_pch_in_use()
|
||||
# The gate's choice, cached by configure
|
||||
if pch.pch_needs_gcc_check() and get_cmake_cache_value(_PCH_CHOICE_VAR) != "ON":
|
||||
return
|
||||
pch.log_pch_in_use()
|
||||
checksum = pch.pch_checksum(
|
||||
CORE.relative_src_path(),
|
||||
pch.PCH_DEFAULT_HEADERS,
|
||||
|
||||
@@ -3,68 +3,21 @@ resolution, and default ``CCACHE_*`` values."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
from esphome.framework_helpers import (
|
||||
strip_win_long_path_prefix,
|
||||
tool_version_probe,
|
||||
tool_version_runs,
|
||||
)
|
||||
from esphome.framework_helpers import strip_win_long_path_prefix, tool_version_runs
|
||||
from esphome.helpers import FALSY_ENV_STRINGS, TRUTHY_ENV_STRINGS
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Before 4.7 ccache stores a pch consumer whose header is newer than one
|
||||
# second without that header, so a later build reuses it after the header
|
||||
# changed (#21621)
|
||||
CCACHE_PCH_MIN_VERSION = (4, 7)
|
||||
|
||||
_VERSION_RE = re.compile(r"ccache version (\d+(?:\.\d+)*)")
|
||||
|
||||
|
||||
@functools.cache
|
||||
def _ccache_probe(ccache: str) -> str | Exception:
|
||||
"""``ccache --version``, run once per binary per process."""
|
||||
return tool_version_probe(ccache)
|
||||
|
||||
|
||||
def _ccache_runs(ccache: str) -> bool:
|
||||
"""Return True when the ``ccache`` found on PATH actually runs."""
|
||||
return tool_version_runs(
|
||||
ccache,
|
||||
"Ignoring ccache at %s because it failed to run; compiling without ccache",
|
||||
probe=_ccache_probe,
|
||||
)
|
||||
|
||||
|
||||
@functools.cache
|
||||
def _ccache_too_old_for_pch(ccache: str) -> bool:
|
||||
output = _ccache_probe(ccache)
|
||||
if not isinstance(output, str) or (found := _VERSION_RE.search(output)) is None:
|
||||
return False
|
||||
if tuple(map(int, found[1].split("."))) >= CCACHE_PCH_MIN_VERSION:
|
||||
return False
|
||||
_LOGGER.info(
|
||||
"ccache %s at %s can reuse stale objects with a precompiled header; "
|
||||
"compiling without it (upgrade ccache to %s or newer, or set "
|
||||
"ESPHOME_PCH_ENABLE=1 to force)",
|
||||
found[1],
|
||||
ccache,
|
||||
".".join(map(str, CCACHE_PCH_MIN_VERSION)),
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
def ccache_breaks_pch() -> bool:
|
||||
"""Whether the ccache this build uses is too old for a precompiled header.
|
||||
ESP-IDF builds check the ccache IDF finds in CMake instead (build_gen.espidf)."""
|
||||
return (ccache := resolve_ccache_path()) is not None and _ccache_too_old_for_pch(
|
||||
ccache
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -12,11 +12,7 @@ import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from esphome.build_helpers.ccache import (
|
||||
ccache_breaks_pch,
|
||||
effective_ccache_basedir,
|
||||
parse_enable_env,
|
||||
)
|
||||
from esphome.build_helpers.ccache import effective_ccache_basedir, parse_enable_env
|
||||
from esphome.const import PLATFORM_NRF52
|
||||
from esphome.helpers import write_file_if_changed
|
||||
|
||||
@@ -121,16 +117,9 @@ def pch_needs_gcc_check() -> bool:
|
||||
return sys.platform == "win32" and parse_enable_env("ESPHOME_PCH_ENABLE") is None
|
||||
|
||||
|
||||
def _ccache_rules_out_pch() -> bool:
|
||||
"""An old ccache, unless ``ESPHOME_PCH_ENABLE=1`` forces the pch on.
|
||||
ESP-IDF runs the same check in CMake (build_gen.espidf)."""
|
||||
return not pch_forced() and ccache_breaks_pch()
|
||||
|
||||
|
||||
def pch_usable(cxx: Sequence[Path | str]) -> bool:
|
||||
"""The knob plus the ccache and host rules; ``ESPHOME_PCH_ENABLE=1``
|
||||
skips the rules."""
|
||||
if not pch_enabled() or _ccache_rules_out_pch():
|
||||
"""The knob plus the host rule; ``ESPHOME_PCH_ENABLE=1`` skips the rule."""
|
||||
if not pch_enabled():
|
||||
return False
|
||||
if not pch_needs_gcc_check():
|
||||
return True
|
||||
@@ -173,11 +162,7 @@ def pch_script_enabled() -> bool:
|
||||
"""Whether this PlatformIO build takes the pch script."""
|
||||
from esphome.core import CORE
|
||||
|
||||
return (
|
||||
pch_enabled()
|
||||
and CORE.target_platform not in PCH_SCRIPT_EXCLUDED_PLATFORMS
|
||||
and not _ccache_rules_out_pch()
|
||||
)
|
||||
return pch_enabled() and CORE.target_platform not in PCH_SCRIPT_EXCLUDED_PLATFORMS
|
||||
|
||||
|
||||
def pch_header_text(include_headers: Iterable[str]) -> str:
|
||||
|
||||
@@ -108,8 +108,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
def _final_validate(config: ConfigType) -> ConfigType:
|
||||
full = fv.full_config.get()
|
||||
hub = full.get_config_for_path(full.get_path_for_id(config[CONF_AS734X_ID])[:-1])
|
||||
hub = fv.get_declaring_config(config[CONF_AS734X_ID])
|
||||
if hub[CONF_TYPE] != "AS7341":
|
||||
return config
|
||||
for key in _BAND_KEYS:
|
||||
|
||||
@@ -66,9 +66,7 @@ CONFIG_SCHEMA = cv.typed_schema(
|
||||
def _final_validate(config: ConfigType) -> None:
|
||||
if config[CONF_TYPE] not in _MAGNETIC_FIELDS:
|
||||
return
|
||||
full_config = fv.full_config.get()
|
||||
bmi270_path = full_config.get_path_for_id(config[CONF_BMI270_ID])[:-1]
|
||||
bmi270_config = full_config.get_config_for_path(bmi270_path)
|
||||
bmi270_config = fv.get_declaring_config(config[CONF_BMI270_ID])
|
||||
if bmi270_config.get(CONF_AUX_DEVICE) != "BMM150":
|
||||
raise cv.Invalid(
|
||||
"This sensor requires the parent bmi270's 'aux_device' to be set to 'BMM150'",
|
||||
|
||||
@@ -7,6 +7,7 @@ from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_UPDATE_INTERVAL, CONF_WATCHDOG
|
||||
from esphome.core import CORE, ID, EsphomeError, Lambda, TimePeriod
|
||||
import esphome.final_validate as fv
|
||||
from esphome.types import ConfigType, TemplateArgsType
|
||||
|
||||
CODEOWNERS = ["@Rapsssito"]
|
||||
@@ -359,8 +360,7 @@ async def bq25186_configure_to_code(
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
|
||||
# Options the action leaves out fall back to the component's configuration
|
||||
path = CORE.config.get_path_for_id(config[CONF_ID])[:-1]
|
||||
parent_config = CORE.config.get_config_for_path(path)
|
||||
parent_config = fv.get_declaring_config(config[CONF_ID], CORE.config)
|
||||
merged = {**parent_config, **config}
|
||||
try:
|
||||
_check_watchdog(merged)
|
||||
|
||||
@@ -13,10 +13,19 @@ from esphome.const import (
|
||||
from esphome.core.entity_helpers import inherit_property_from
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(sensor.Sensor).extend(
|
||||
{
|
||||
cv.Required(CONF_SOURCE_ID): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
from .. import copy_ns
|
||||
|
||||
CopySensor = copy_ns.class_("CopySensor", sensor.Sensor, cg.Component)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(CopySensor)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_SOURCE_ID): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
@@ -31,4 +40,6 @@ FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
var = await sensor.new_sensor(config)
|
||||
sensor.follow_sensor(var, await cg.get_variable(config[CONF_SOURCE_ID]))
|
||||
await cg.register_component(var, config)
|
||||
|
||||
await cg.add_variable(var.set_source, config[CONF_SOURCE_ID])
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "copy_sensor.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome::copy {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "copy.sensor");
|
||||
|
||||
void CopySensor::setup() {
|
||||
source_->add_on_state_callback([this](float value) { this->publish_state(value); });
|
||||
if (source_->has_state())
|
||||
this->publish_state(source_->state);
|
||||
}
|
||||
|
||||
void CopySensor::dump_config() { LOG_SENSOR("", "Copy Sensor", this); }
|
||||
|
||||
} // namespace esphome::copy
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome::copy {
|
||||
|
||||
class CopySensor final : public sensor::Sensor, public Component {
|
||||
public:
|
||||
void set_source(sensor::Sensor *source) { source_ = source; }
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
sensor::Sensor *source_;
|
||||
};
|
||||
|
||||
} // namespace esphome::copy
|
||||
@@ -5,10 +5,19 @@ from esphome.const import CONF_ENTITY_CATEGORY, CONF_ICON, CONF_SOURCE_ID
|
||||
from esphome.core.entity_helpers import inherit_property_from
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CONFIG_SCHEMA = text_sensor.text_sensor_schema(text_sensor.TextSensor).extend(
|
||||
{
|
||||
cv.Required(CONF_SOURCE_ID): cv.use_id(text_sensor.TextSensor),
|
||||
}
|
||||
from .. import copy_ns
|
||||
|
||||
CopyTextSensor = copy_ns.class_("CopyTextSensor", text_sensor.TextSensor, cg.Component)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
text_sensor.text_sensor_schema(CopyTextSensor)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_SOURCE_ID): cv.use_id(text_sensor.TextSensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
@@ -19,4 +28,6 @@ FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
var = await text_sensor.new_text_sensor(config)
|
||||
text_sensor.follow_text_sensor(var, await cg.get_variable(config[CONF_SOURCE_ID]))
|
||||
await cg.register_component(var, config)
|
||||
|
||||
await cg.add_variable(var.set_source, config[CONF_SOURCE_ID])
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "copy_text_sensor.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome::copy {
|
||||
|
||||
ESPHOME_LOG_TAG(TAG, "copy.text_sensor");
|
||||
|
||||
void CopyTextSensor::setup() {
|
||||
source_->add_on_state_callback([this](const std::string &value) { this->publish_state(value); });
|
||||
if (source_->has_state())
|
||||
this->publish_state(source_->state);
|
||||
}
|
||||
|
||||
void CopyTextSensor::dump_config() { LOG_TEXT_SENSOR("", "Copy Sensor", this); }
|
||||
|
||||
} // namespace esphome::copy
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
|
||||
namespace esphome::copy {
|
||||
|
||||
class CopyTextSensor final : public text_sensor::TextSensor, public Component {
|
||||
public:
|
||||
void set_source(text_sensor::TextSensor *source) { source_ = source; }
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
text_sensor::TextSensor *source_;
|
||||
};
|
||||
|
||||
} // namespace esphome::copy
|
||||
@@ -3,8 +3,7 @@ from collections.abc import Callable
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import uart
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_MODE, CONF_MODEL
|
||||
from esphome.core import ID
|
||||
from esphome.const import CONF_MODE, CONF_MODEL
|
||||
import esphome.final_validate as fv
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -59,16 +58,11 @@ FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
|
||||
)
|
||||
|
||||
|
||||
def get_hub_config(root: ConfigType, hub_id: ID) -> ConfigType:
|
||||
"""Return the configuration of the hub with the given id."""
|
||||
return next(conf for conf in root[DOMAIN] if conf[CONF_ID] == hub_id)
|
||||
|
||||
|
||||
def final_validate_mode(keys: dict[str, str]) -> Callable[[ConfigType], None]:
|
||||
"""Reject entity keys that need a different hub mode; `keys` maps each key to the mode it needs."""
|
||||
|
||||
def validator(config: ConfigType) -> None:
|
||||
hub = get_hub_config(fv.full_config.get(), config[CONF_DFROBOT_SEN0609_ID])
|
||||
hub = fv.get_declaring_config(config[CONF_DFROBOT_SEN0609_ID])
|
||||
for key, mode in keys.items():
|
||||
if key in config and hub[CONF_MODE] != mode:
|
||||
raise cv.Invalid(
|
||||
|
||||
@@ -18,6 +18,7 @@ from esphome.const import (
|
||||
UNIT_SECOND,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
import esphome.final_validate as fv
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import (
|
||||
@@ -28,7 +29,6 @@ from .. import (
|
||||
DFRobotSEN0609Component,
|
||||
dfrobot_sen0609_ns,
|
||||
final_validate_mode,
|
||||
get_hub_config,
|
||||
)
|
||||
|
||||
DFRobotSEN0609Number = dfrobot_sen0609_ns.class_("DFRobotSEN0609Number", number.Number)
|
||||
@@ -181,7 +181,7 @@ FINAL_VALIDATE_SCHEMA = final_validate_mode(
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
hub_id = config[CONF_DFROBOT_SEN0609_ID]
|
||||
hub = await cg.get_variable(hub_id)
|
||||
max_range = MAX_RANGES[get_hub_config(CORE.config, hub_id)[CONF_MODEL]]
|
||||
max_range = MAX_RANGES[fv.get_declaring_config(hub_id, CORE.config)[CONF_MODEL]]
|
||||
numbers = number.sub_numbers(config, parent=hub)
|
||||
for s in SETTINGS:
|
||||
await numbers(
|
||||
|
||||
@@ -28,7 +28,7 @@ from esphome.const import (
|
||||
SCHEDULER_DONT_RUN,
|
||||
)
|
||||
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
|
||||
from esphome.final_validate import full_config
|
||||
from esphome.final_validate import full_config, get_declaring_config
|
||||
from esphome.types import ConfigType
|
||||
|
||||
DOMAIN = "display"
|
||||
@@ -225,9 +225,7 @@ def get_display_metadata(display_id: ID) -> DisplayMetaData:
|
||||
return meta
|
||||
# No metadata found, display driver may not yet support it.
|
||||
# Read the raw config to populate the returned data
|
||||
global_config = full_config.get()
|
||||
path = global_config.get_path_for_id(display_id)[:-1]
|
||||
disp_config = global_config.get_config_for_path(path)
|
||||
disp_config = get_declaring_config(display_id)
|
||||
dimensions = disp_config.get(CONF_DIMENSIONS, (0, 0))
|
||||
if isinstance(dimensions, dict):
|
||||
dimensions = (dimensions.get(CONF_WIDTH, 0), dimensions.get(CONF_HEIGHT, 0))
|
||||
|
||||
@@ -32,9 +32,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
def _final_validate(config: ConfigType) -> None:
|
||||
"""Validate that the channel is within the parent's channel count."""
|
||||
fconf = fv.full_config.get()
|
||||
path = fconf.get_path_for_id(config[CONF_DS248X_ID])[:-1]
|
||||
parent_config = fconf.get_config_for_path(path)
|
||||
parent_config = fv.get_declaring_config(config[CONF_DS248X_ID])
|
||||
channel_count = get_channel_count(parent_config)
|
||||
channel = config[CONF_CHANNEL]
|
||||
|
||||
|
||||
@@ -63,9 +63,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
def _validate_model(config: ConfigType) -> None:
|
||||
full_config = fv.full_config.get()
|
||||
climate_path = full_config.get_path_for_id(config[CONF_GREE_ID])[:-1]
|
||||
climate_conf = full_config.get_config_for_path(climate_path)
|
||||
climate_conf = fv.get_declaring_config(config[CONF_GREE_ID])
|
||||
if climate_conf[CONF_MODEL] not in SUPPORTED_MODELS:
|
||||
raise cv.Invalid(
|
||||
"Gree switches are only supported for the "
|
||||
|
||||
@@ -61,12 +61,10 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
def _final_validate(config) -> None:
|
||||
full_config = fv.full_config.get()
|
||||
for switch_type in [CONF_BEEPER, CONF_QUIET_MODE]:
|
||||
# Check switches that are only supported for HonClimate
|
||||
if config.get(switch_type):
|
||||
climate_path = full_config.get_path_for_id(config[CONF_HAIER_ID])[:-1]
|
||||
climate_conf = full_config.get_config_for_path(climate_path)
|
||||
climate_conf = fv.get_declaring_config(config[CONF_HAIER_ID])
|
||||
protocol_type = climate_conf.get(CONF_PROTOCOL)
|
||||
if protocol_type.casefold() != PROTOCOL_HON.casefold():
|
||||
raise cv.Invalid(
|
||||
|
||||
@@ -42,9 +42,7 @@ def _final_validate(config: dict[str, Any]) -> None:
|
||||
|
||||
# Get the transmitter configuration
|
||||
transmitter_id = config[CONF_REMOTE_TRANSMITTER_ID]
|
||||
full_config = fv.full_config.get()
|
||||
transmitter_path = full_config.get_path_for_id(transmitter_id)[:-1]
|
||||
transmitter_config = full_config.get_config_for_path(transmitter_path)
|
||||
transmitter_config = fv.get_declaring_config(transmitter_id)
|
||||
|
||||
# Check if carrier_duty_percent set to 0 or 100
|
||||
# Note: remote_transmitter schema requires this field and validates 1-100%,
|
||||
|
||||
@@ -35,11 +35,7 @@ def _final_validate(config: ConfigType) -> None:
|
||||
if CONF_REMOTE_TRANSMITTER_ID not in config:
|
||||
return
|
||||
|
||||
full_config = fv.full_config.get()
|
||||
transmitter_path = full_config.get_path_for_id(config[CONF_REMOTE_TRANSMITTER_ID])[
|
||||
:-1
|
||||
]
|
||||
transmitter_config = full_config.get_config_for_path(transmitter_path)
|
||||
transmitter_config = fv.get_declaring_config(config[CONF_REMOTE_TRANSMITTER_ID])
|
||||
|
||||
duty_percent = transmitter_config.get(CONF_CARRIER_DUTY_PERCENT)
|
||||
if duty_percent is not None and duty_percent != 100:
|
||||
|
||||
@@ -101,8 +101,7 @@ def final_validate(config: ConfigType) -> None:
|
||||
)
|
||||
|
||||
if config.get(CONF_WAKE):
|
||||
hub_path = full_config.get_path_for_id(hub_id)
|
||||
hub_config = full_config.get_config_for_path(hub_path[:-1])
|
||||
hub_config = fv.get_declaring_config(hub_id, full_config)
|
||||
if hub_config.get(CONF_WAKEUP_PIN) is None:
|
||||
raise cv.Invalid(
|
||||
f"{CONF_WAKE} requires {CONF_WAKEUP_PIN} on the parent ld6002b component",
|
||||
|
||||
@@ -380,8 +380,7 @@ def _final_validate(config: ConfigType) -> None:
|
||||
|
||||
for ref in refs:
|
||||
try:
|
||||
light_path = fconf.get_path_for_id(ref.light_id)[:-1]
|
||||
light_config = fconf.get_config_for_path(light_path)
|
||||
light_config = fv.get_declaring_config(ref.light_id, fconf)
|
||||
except KeyError:
|
||||
# Light ID not found — ID validation will have already reported this
|
||||
continue
|
||||
@@ -398,8 +397,7 @@ def _final_validate(config: ConfigType) -> None:
|
||||
|
||||
for ref in cycle_refs:
|
||||
try:
|
||||
light_path = fconf.get_path_for_id(ref.light_id)[:-1]
|
||||
light_config = fconf.get_config_for_path(light_path)
|
||||
light_config = fv.get_declaring_config(ref.light_id, fconf)
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.core import CORE, ID, EsphomeError, Lambda
|
||||
from esphome.cpp_generator import MockObj, TemplateArgsType
|
||||
import esphome.final_validate as fv
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -253,8 +254,7 @@ def _resolve_effect_index(config: ConfigType, original_name: str) -> int:
|
||||
from . import effect_not_found_message, find_effect_index
|
||||
|
||||
light_id = config[CONF_ID]
|
||||
light_path = CORE.config.get_path_for_id(light_id)[:-1]
|
||||
light_config = CORE.config.get_config_for_path(light_path)
|
||||
light_config = fv.get_declaring_config(light_id, CORE.config)
|
||||
effects = light_config.get(CONF_EFFECTS, [])
|
||||
index = find_effect_index(effects, original_name)
|
||||
if index is not None:
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import logging
|
||||
|
||||
from esphome import automation, pins
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
@@ -17,8 +15,6 @@ from esphome.core import CORE
|
||||
from esphome.cpp_helpers import gpio_pin_expression
|
||||
from esphome.types import ConfigType
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CODEOWNERS = ["@max246"]
|
||||
DOMAIN = "lightwaverf"
|
||||
|
||||
@@ -39,20 +35,10 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
).extend(cv.polling_component_schema("1s"))
|
||||
|
||||
|
||||
def _drop_unused_name(config: ConfigType) -> ConfigType:
|
||||
# Remove before 2027.5.0
|
||||
if config.pop(CONF_NAME, None) is not None:
|
||||
_LOGGER.warning(
|
||||
"[lightwaverf] 'name' on lightwaverf.send_raw has no effect; remove it. "
|
||||
"Removed in 2027.5.0"
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
LIGHTWAVE_SEND_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(LIGHTWAVERFComponent),
|
||||
cv.Optional(CONF_NAME): cv.string,
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
cv.Required(CONF_CODE): cv.All(
|
||||
[cv.Any(cv.hex_uint8_t)],
|
||||
cv.Length(min=10),
|
||||
@@ -61,7 +47,7 @@ LIGHTWAVE_SEND_SCHEMA = cv.Schema(
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PULSE_LENGTH, default=330): cv.int_,
|
||||
}
|
||||
).add_extra(_drop_unused_name)
|
||||
)
|
||||
|
||||
|
||||
automation.register_apply_action(
|
||||
|
||||
@@ -41,9 +41,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
|
||||
|
||||
def _final_validate(config: ConfigType) -> None:
|
||||
full_config = fv.full_config.get()
|
||||
display_path = full_config.get_path_for_id(config[CONF_DISPLAY_ID])[:-1]
|
||||
display_config = full_config.get_config_for_path(display_path)
|
||||
display_config = fv.get_declaring_config(config[CONF_DISPLAY_ID])
|
||||
if CONF_BRIGHTNESS not in display_config:
|
||||
model = display_config[CONF_MODEL]
|
||||
if model == "CUSTOM":
|
||||
|
||||
@@ -310,9 +310,7 @@ def migrate_custom_command(config: ConfigType) -> None:
|
||||
frame = config.get(CONF_CUSTOM_COMMAND)
|
||||
if frame is None:
|
||||
return
|
||||
fconf = fv.full_config.get()
|
||||
path = fconf.get_path_for_id(config[CONF_MODBUS_CONTROLLER_ID])[:-1]
|
||||
controller = fconf.get_config_for_path(path)
|
||||
controller = fv.get_declaring_config(config[CONF_MODBUS_CONTROLLER_ID])
|
||||
# the controller's DEVICE address (from modbus_device_schema)
|
||||
address = controller[CONF_ADDRESS]
|
||||
if frame[0] != address:
|
||||
@@ -342,9 +340,7 @@ def _reject_continuous_write_custom_pdu(config: ConfigType) -> None:
|
||||
pdu = config.get(CONF_CUSTOM_PDU)
|
||||
if pdu is None or not modbus.is_function_code_write(pdu[0]):
|
||||
return
|
||||
fconf = fv.full_config.get()
|
||||
path = fconf.get_path_for_id(config[CONF_MODBUS_CONTROLLER_ID])[:-1]
|
||||
controller = fconf.get_config_for_path(path)
|
||||
controller = fv.get_declaring_config(config[CONF_MODBUS_CONTROLLER_ID])
|
||||
if controller.get(CONF_CONTINUOUS) is True:
|
||||
raise cv.Invalid(
|
||||
f"a '{CONF_CUSTOM_PDU}' with a write function code (0x{pdu[0] & 0x7F:02X}) can't be polled "
|
||||
@@ -359,9 +355,7 @@ def _reject_broadcastable_custom_pdu(config: ConfigType) -> None:
|
||||
pdu = config.get(CONF_CUSTOM_PDU)
|
||||
if pdu is None or not modbus.is_function_code_broadcastable(pdu[0]):
|
||||
return
|
||||
fconf = fv.full_config.get()
|
||||
path = fconf.get_path_for_id(config[CONF_MODBUS_CONTROLLER_ID])[:-1]
|
||||
controller = fconf.get_config_for_path(path)
|
||||
controller = fv.get_declaring_config(config[CONF_MODBUS_CONTROLLER_ID])
|
||||
if (
|
||||
controller.get(CONF_ADDRESS) == modbus.BROADCAST_ADDRESS
|
||||
and controller.get(modbus.CONF_ALLOW_BROADCAST_READ) is True
|
||||
@@ -384,9 +378,7 @@ def validate_custom_pdu_item(config: ConfigType) -> None:
|
||||
def _reject_write_option_off_broadcast(config: ConfigType) -> None:
|
||||
if not any(config.get(key) is True for key in modbus.broadcast_only_option_keys()):
|
||||
return
|
||||
fconf = fv.full_config.get()
|
||||
path = fconf.get_path_for_id(config[CONF_MODBUS_CONTROLLER_ID])[:-1]
|
||||
controller = fconf.get_config_for_path(path)
|
||||
controller = fv.get_declaring_config(config[CONF_MODBUS_CONTROLLER_ID])
|
||||
if controller.get(CONF_ADDRESS) != modbus.BROADCAST_ADDRESS:
|
||||
raise cv.Invalid(
|
||||
f"'{modbus.CONF_EXPECT_BROADCAST_WRITE_RESPONSE}' only applies when the "
|
||||
|
||||
@@ -50,9 +50,7 @@ MAX_RECOMMENDED_UPDATE_INTERVAL_MS = 100
|
||||
|
||||
def get_motion_config(motion_id: ID) -> dict:
|
||||
"""Look up the (already-validated) config of the motion hub referenced by motion_id."""
|
||||
full_config = fv.full_config.get()
|
||||
motion_path = full_config.get_path_for_id(motion_id)[:-1]
|
||||
return full_config.get_config_for_path(motion_path)
|
||||
return fv.get_declaring_config(motion_id)
|
||||
|
||||
|
||||
def check_update_interval(motion_id: ID, feature_name: str) -> None:
|
||||
|
||||
@@ -67,8 +67,7 @@ def _final_validate(config: ConfigType) -> None:
|
||||
"Max touch channel must equal the highest binary sensor channel or be removed for auto calculation",
|
||||
path=[CONF_MAX_TOUCH_CHANNEL],
|
||||
)
|
||||
path = fconf.get_path_for_id(config[CONF_ID])[:-1]
|
||||
this_config = fconf.get_config_for_path(path)
|
||||
this_config = fv.get_declaring_config(config[CONF_ID], fconf)
|
||||
this_config[CONF_MAX_TOUCH_CHANNEL] = max_touch_channel
|
||||
|
||||
|
||||
|
||||
@@ -48,9 +48,7 @@ def _final_validate(config: ConfigType) -> None:
|
||||
if config[CONF_TYPE] != CONF_STATUS:
|
||||
# Only run this validation if a status sensor is being configured
|
||||
return
|
||||
full_config = fv.full_config.get()
|
||||
transport_path = full_config.get_path_for_id(config[CONF_TRANSPORT_ID])[:-1]
|
||||
transport_config = full_config.get_config_for_path(transport_path)
|
||||
transport_config = fv.get_declaring_config(config[CONF_TRANSPORT_ID])
|
||||
if transport_config[CONF_PING_PONG_ENABLE] and any(
|
||||
CONF_ENCRYPTION in p
|
||||
for p in transport_config[CONF_PROVIDERS]
|
||||
|
||||
@@ -35,11 +35,8 @@ def validate_from_to(value: ConfigType) -> ConfigType:
|
||||
|
||||
|
||||
def validate_segment(config: ConfigType) -> None:
|
||||
fconf = fv.full_config.get()
|
||||
|
||||
if CONF_ID in config: # only validate addressable segments
|
||||
path = fconf.get_path_for_id(config[CONF_ID])[:-1]
|
||||
segment_light_config = fconf.get_config_for_path(path)
|
||||
segment_light_config = fv.get_declaring_config(config[CONF_ID])
|
||||
|
||||
if CONF_NUM_LEDS in segment_light_config:
|
||||
segment_len = segment_light_config[CONF_NUM_LEDS]
|
||||
|
||||
@@ -124,7 +124,6 @@ from esphome.core import (
|
||||
)
|
||||
from esphome.core.config import UNIT_OF_MEASUREMENT_MAX_LENGTH
|
||||
from esphome.core.entity_helpers import (
|
||||
FollowEntity,
|
||||
SubEntities,
|
||||
entity_duplicate_validator,
|
||||
lazy_load_validator,
|
||||
@@ -1110,10 +1109,6 @@ def sub_sensors(
|
||||
return SubEntities(new_sensor, config, parent)
|
||||
|
||||
|
||||
# Makes a plain sensor follow another sensor: follow_sensor(entity, source)
|
||||
follow_sensor = FollowEntity("add_on_state_callback", ((cg.float_, "x"),), "x")
|
||||
|
||||
|
||||
SENSOR_IN_RANGE_CONDITION_SCHEMA = cv.All(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(Sensor),
|
||||
|
||||
@@ -56,9 +56,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
def _final_validate(config: ConfigType) -> ConfigType:
|
||||
fconf = fv.full_config.get()
|
||||
hub_path = fconf.get_path_for_id(config[CONF_TAS58XX_ID])
|
||||
hub_conf = fconf.get_config_for_path(hub_path[:-1])
|
||||
hub_conf = fv.get_declaring_config(config[CONF_TAS58XX_ID])
|
||||
|
||||
if hub_conf[CONF_MODEL] == DAC_TAS5825M:
|
||||
return config
|
||||
|
||||
@@ -65,9 +65,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
|
||||
def _final_validate(config: ConfigType) -> None:
|
||||
"""Resolve the key to the number the device reports, checked against the keypad's matrix."""
|
||||
full_config = fv.full_config.get()
|
||||
keypad_path = full_config.get_path_for_id(config[CONF_KEYPAD_ID])[:-1]
|
||||
keypad = full_config.get_config_for_path(keypad_path)
|
||||
keypad = fv.get_declaring_config(config[CONF_KEYPAD_ID])
|
||||
rows = keypad.get(CONF_ROWS, 0)
|
||||
columns = keypad.get(CONF_COLUMNS, 0)
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
|
||||
from esphome.core.entity_helpers import (
|
||||
FollowEntity,
|
||||
SubEntities,
|
||||
entity_duplicate_validator,
|
||||
queue_entity_register,
|
||||
@@ -239,12 +238,6 @@ def sub_text_sensors(
|
||||
return SubEntities(new_text_sensor, config, parent)
|
||||
|
||||
|
||||
# Makes a plain text sensor follow another text sensor: follow_text_sensor(entity, source)
|
||||
follow_text_sensor = FollowEntity(
|
||||
"add_on_state_callback", ((cg.std_string_ref.operator("const"), "x"),), "x"
|
||||
)
|
||||
|
||||
|
||||
@coroutine_with_priority(CoroPriority.CORE)
|
||||
async def to_code(config):
|
||||
cg.add_global(text_sensor_ns.using)
|
||||
|
||||
@@ -59,9 +59,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
def _final_validate(config: ConfigType) -> ConfigType:
|
||||
if CONF_ACTUAL_CURRENT not in config:
|
||||
return config
|
||||
full_config = fv.full_config.get()
|
||||
path = full_config.get_path_for_id(config[CONF_TMC2209_ID])[:-1]
|
||||
if full_config.get_config_for_path(path).get(CONF_ANALOG_CURRENT_SCALE):
|
||||
if fv.get_declaring_config(config[CONF_TMC2209_ID]).get(CONF_ANALOG_CURRENT_SCALE):
|
||||
raise cv.Invalid(
|
||||
f"'{CONF_ACTUAL_CURRENT}' can't be used with '{CONF_ANALOG_CURRENT_SCALE}', "
|
||||
"the current then depends on VREF",
|
||||
|
||||
@@ -56,8 +56,7 @@ _validate_unique = unique_child("number")
|
||||
|
||||
def _final_validate(config: ConfigType) -> ConfigType:
|
||||
_validate_unique(config)
|
||||
full = fv.full_config.get()
|
||||
parent = full.get_config_for_path(full.get_path_for_id(config[CONF_TMP102_ID])[:-1])
|
||||
parent = fv.get_declaring_config(config[CONF_TMP102_ID])
|
||||
add_number_parent(config[CONF_TMP102_ID], parent.get(CONF_EXTENDED_MODE, False))
|
||||
return config
|
||||
|
||||
|
||||
+1
-3
@@ -1136,9 +1136,7 @@ class IDPassValidationStep(ConfigValidationStep):
|
||||
m
|
||||
for m in matches
|
||||
if isinstance(
|
||||
candidate_conf := result.get_config_for_path(
|
||||
result.get_path_for_id(m)[:-1]
|
||||
),
|
||||
candidate_conf := fv.get_declaring_config(m, result),
|
||||
dict,
|
||||
)
|
||||
and all(
|
||||
|
||||
@@ -416,13 +416,10 @@ void Application::teardown_components(uint32_t timeout_ms) {
|
||||
}
|
||||
}
|
||||
|
||||
void Application::add_looping_components_by_state_(bool inactive) {
|
||||
void Application::add_looping_components_by_state_(bool match_loop_done) {
|
||||
for (auto *obj : this->components_) {
|
||||
if (!obj->has_overridden_loop()) {
|
||||
continue;
|
||||
}
|
||||
const uint8_t state = obj->get_component_state() & COMPONENT_STATE_MASK;
|
||||
if ((state == COMPONENT_STATE_LOOP_DONE || state == COMPONENT_STATE_FAILED) == inactive) {
|
||||
if (obj->has_overridden_loop() &&
|
||||
((obj->get_component_state() & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) == match_loop_done) {
|
||||
this->looping_components_.push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,15 +433,16 @@ class Application {
|
||||
// FixedVector capacity was pre-initialized by codegen with the exact count
|
||||
// of components that override loop(), computed at C++ compile time.
|
||||
|
||||
// Add all components with loop override that aren't already LOOP_DONE or FAILED
|
||||
// Some components (like logger) may call disable_loop() during initialization,
|
||||
// and some call mark_failed() from their constructor, before setup runs
|
||||
// Add all components with loop override that aren't already LOOP_DONE
|
||||
// Some components (like logger) may call disable_loop() during initialization
|
||||
// before setup runs, so we need to respect their LOOP_DONE state
|
||||
this->add_looping_components_by_state_(false);
|
||||
this->looping_components_active_end_ = this->looping_components_.size();
|
||||
// Then add any components that are already LOOP_DONE or FAILED to the inactive section
|
||||
// Then add any components that are already LOOP_DONE to the inactive section
|
||||
// This handles components that called disable_loop() during initialization
|
||||
this->add_looping_components_by_state_(true);
|
||||
}
|
||||
void add_looping_components_by_state_(bool inactive);
|
||||
void add_looping_components_by_state_(bool match_loop_done);
|
||||
|
||||
// These methods are called by Component::disable_loop() and Component::enable_loop()
|
||||
// Components should not call these directly - use this->disable_loop() or this->enable_loop()
|
||||
|
||||
@@ -169,7 +169,7 @@ struct Color {
|
||||
uint8_t r = rand >> 16;
|
||||
uint8_t g = rand >> 8;
|
||||
uint8_t b = rand >> 0;
|
||||
const uint16_t max_rgb = std::max({r, g, b, uint8_t(1)});
|
||||
const uint16_t max_rgb = std::max({r, g, b});
|
||||
return Color(uint8_t((uint16_t(r) * 255U / max_rgb)), uint8_t((uint16_t(g) * 255U / max_rgb)),
|
||||
uint8_t((uint16_t(b) * 255U / max_rgb)), w);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ from esphome.core.config import (
|
||||
UNIT_OF_MEASUREMENT_MAX_LENGTH,
|
||||
)
|
||||
from esphome.cpp_generator import (
|
||||
LambdaExpression,
|
||||
MockObj,
|
||||
MockObjClass,
|
||||
RawExpression,
|
||||
@@ -520,23 +519,6 @@ class ApplyEntity:
|
||||
_APPLY_DOMAIN = "entity_apply"
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class FollowEntity:
|
||||
"""A state callback, its parameters and the value an entity republishes from it."""
|
||||
|
||||
callback: str
|
||||
params: tuple[tuple[SafeExpType, str], ...]
|
||||
value: str
|
||||
|
||||
def __call__(self, entity: MockObj, source: MockObj, *args: SafeExpType) -> None:
|
||||
"""Make ``entity`` publish every state of ``source``; ``args`` precede the callback."""
|
||||
publish = f"{parent_ref(entity).publish_state(RawExpression(self.value))};"
|
||||
callback = LambdaExpression(
|
||||
[publish], list(self.params), capture="", return_type=cg.void
|
||||
)
|
||||
add(getattr(source, self.callback)(*args, callback))
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class SubEntities:
|
||||
"""Create the child entity configured under key, set parent (if bound) and pass it to setter.
|
||||
@@ -664,14 +646,12 @@ def inherit_property_from(property_to_inherit, parent_id_property, transform=Non
|
||||
|
||||
# Get config for the parent entity
|
||||
parent_id = _walk_config(config, parent_id_property)
|
||||
parent_path = fconf.get_path_for_id(parent_id)[:-1]
|
||||
parent_config = fconf.get_config_for_path(parent_path)
|
||||
parent_config = fv.get_declaring_config(parent_id, fconf)
|
||||
|
||||
# If parent sensor has the property set, inherit it
|
||||
if property in parent_config:
|
||||
path = fconf.get_path_for_id(config[CONF_ID])[:-1]
|
||||
this_config = _walk_config(
|
||||
fconf.get_config_for_path(path), property_path
|
||||
fv.get_declaring_config(config[CONF_ID], fconf), property_path
|
||||
)
|
||||
value = parent_config[property]
|
||||
if transform:
|
||||
|
||||
@@ -331,8 +331,6 @@ class FloatLiteral(Literal):
|
||||
def __str__(self):
|
||||
if math.isnan(self.f):
|
||||
return "NAN"
|
||||
if math.isinf(self.f):
|
||||
return "INFINITY" if self.f > 0 else "-INFINITY"
|
||||
return f"{self.f}f"
|
||||
|
||||
|
||||
|
||||
+1
-7
@@ -466,15 +466,9 @@ def receive_exactly(
|
||||
|
||||
while len(data) < amount:
|
||||
try:
|
||||
chunk = recv_decode(sock, amount - len(data), decode=decode)
|
||||
data += recv_decode(sock, amount - len(data), decode=decode) # type: ignore[operator]
|
||||
except OSError as err:
|
||||
raise OTANetworkError(f"receiving {msg}: {err}") from err
|
||||
if not chunk:
|
||||
raise OTANetworkError(
|
||||
f"receiving {msg}: device closed connection after "
|
||||
f"{len(data)} of {amount} bytes"
|
||||
)
|
||||
data += chunk # type: ignore[operator]
|
||||
return data
|
||||
|
||||
|
||||
|
||||
@@ -205,42 +205,28 @@ def run_command(
|
||||
return False, None, None
|
||||
|
||||
|
||||
def tool_version_probe(binary: str) -> str | Exception:
|
||||
"""Run ``binary --version``: its stdout, or the error when it fails to run.
|
||||
def tool_version_runs(binary: str, warning: str) -> bool:
|
||||
"""Probe ``binary --version``; on failure warn with ``warning`` % binary.
|
||||
|
||||
``shutil.which`` proves existence, not runnability (Windows .bat/.cmd
|
||||
shims, stale package-manager shims).
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
subprocess.run(
|
||||
[binary, "--version"],
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
text=True,
|
||||
errors="replace",
|
||||
timeout=15,
|
||||
# Repo-wide convention (posix_spawn fast path)
|
||||
close_fds=False,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError) as err:
|
||||
return err
|
||||
return result.stdout
|
||||
|
||||
|
||||
def tool_version_runs(
|
||||
binary: str,
|
||||
warning: str,
|
||||
probe: Callable[[str], str | Exception] = tool_version_probe,
|
||||
) -> bool:
|
||||
"""Probe ``binary --version``; on failure warn with ``warning`` % binary.
|
||||
``probe`` lets a caller supply a cached probe."""
|
||||
if not isinstance(result := probe(binary), Exception):
|
||||
return True
|
||||
# The cause (permission denied, missing DLL, timeout) is the one detail
|
||||
# the user needs to fix it
|
||||
_LOGGER.warning("%s (%s)", warning % binary, result)
|
||||
return False
|
||||
# The cause (permission denied, missing DLL, timeout) is the one
|
||||
# detail the user needs to fix it
|
||||
_LOGGER.warning("%s (%s)", warning % binary, err)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def run_command_ok(*args, **kwargs) -> bool:
|
||||
|
||||
+2
-2
@@ -23,6 +23,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.core import CORE, ID
|
||||
from esphome.cpp_generator import MockObj, MockObjClass
|
||||
import esphome.final_validate as fv
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||
from esphome.types import ConfigType, SafeExpType
|
||||
|
||||
@@ -231,8 +232,7 @@ class PinRegistry(dict):
|
||||
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)
|
||||
parent_config = fv.get_declaring_config(client_id, fconf)
|
||||
final_val_fun(pin_config, parent_config)
|
||||
allow_others = pin_config.get(CONF_ALLOW_OTHER_USES, False)
|
||||
if count != 1 and not allow_others and not CORE.testing_mode:
|
||||
|
||||
Whitespace-only changes.
@@ -1,24 +0,0 @@
|
||||
"""lightwaverf.send_raw never used name; it is dropped with a warning until 2027.5.0."""
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome.automation import ACTION_REGISTRY
|
||||
import esphome.components.lightwaverf # noqa: F401
|
||||
from esphome.const import CONF_NAME, CONF_REPEAT
|
||||
|
||||
CODE = [0x04, 0x00, 0x00, 0x00, 0x0F, 0x03, 0x0D, 0x09, 0x08, 0x08]
|
||||
|
||||
|
||||
def test_name_is_dropped_with_a_warning(caplog: pytest.LogCaptureFixture) -> None:
|
||||
config = ACTION_REGISTRY["lightwaverf.send_raw"].schema(
|
||||
{"code": CODE, CONF_NAME: "Sofa"}
|
||||
)
|
||||
assert CONF_NAME not in config
|
||||
assert "'name' on lightwaverf.send_raw has no effect" in caplog.text
|
||||
assert "2027.5.0" in caplog.text
|
||||
|
||||
|
||||
def test_name_is_no_longer_required(caplog: pytest.LogCaptureFixture) -> None:
|
||||
config = ACTION_REGISTRY["lightwaverf.send_raw"].schema({"code": CODE})
|
||||
assert config[CONF_REPEAT] == 10
|
||||
assert "lightwaverf" not in caplog.text
|
||||
@@ -36,30 +36,6 @@ esphome:
|
||||
service: notify.html5
|
||||
data:
|
||||
message: Button was pressed
|
||||
- homeassistant.service:
|
||||
service: !lambda 'return std::string("notify.html5");'
|
||||
data:
|
||||
title: Title
|
||||
data_template:
|
||||
message: The value is {{ my_value }}
|
||||
variables:
|
||||
my_value: !lambda 'return std::string("42");'
|
||||
capture_response: true
|
||||
response_template: !lambda 'return std::string("{{ response.value }}");'
|
||||
on_success:
|
||||
- logger.log: "service succeeded"
|
||||
on_error:
|
||||
- logger.log:
|
||||
format: "service failed: %s"
|
||||
args: [error.c_str()]
|
||||
- homeassistant.action:
|
||||
action: weather.get_forecasts
|
||||
data:
|
||||
entity_id: weather.forecast_home
|
||||
capture_response: true
|
||||
response_template: !lambda 'return std::string("{{ response }}");'
|
||||
on_success:
|
||||
- logger.log: "forecast received"
|
||||
- homeassistant.tag_scanned: pulse
|
||||
- homeassistant.action:
|
||||
action: weather.get_forecasts
|
||||
@@ -331,13 +307,6 @@ api:
|
||||
success: false
|
||||
error_message: !lambda 'return error_msg;'
|
||||
|
||||
- action: test_respond_lambda_success
|
||||
variables:
|
||||
ok: bool
|
||||
then:
|
||||
- api.respond:
|
||||
success: !lambda 'return ok;'
|
||||
|
||||
# ==========================================================================
|
||||
# supports_response: optional (auto-detected - api.respond with data)
|
||||
# Has call_id and return_response - client decides if it wants response
|
||||
|
||||
@@ -21,14 +21,6 @@ esphome:
|
||||
id: waveradar
|
||||
frequency: 5800MHz
|
||||
power_consumption: 91uA
|
||||
- at581x.settings:
|
||||
id: waveradar
|
||||
hw_frontend_reset: !lambda return true;
|
||||
sensing_distance: !lambda return 300;
|
||||
protect_time: !lambda return 1500;
|
||||
trigger_base: !lambda return 600;
|
||||
trigger_keep: !lambda return 12000;
|
||||
stage_gain: !lambda return 4;
|
||||
- at581x.reset:
|
||||
id: waveradar
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ esphome:
|
||||
- bk72xx_ble_tracker.start_scan
|
||||
- bk72xx_ble_tracker.start_scan:
|
||||
continuous: true
|
||||
- bk72xx_ble_tracker.start_scan:
|
||||
continuous: !lambda return false;
|
||||
- bk72xx_ble_tracker.stop_scan
|
||||
- bk72xx_ble_tracker.stop_scan: ble_tracker
|
||||
|
||||
|
||||
@@ -109,10 +109,3 @@ button:
|
||||
- logger.log: Level calibration failed
|
||||
- motion.calibrate_heading:
|
||||
id: bmi270_motion
|
||||
- motion.calibrate_heading:
|
||||
id: bmi270_motion
|
||||
save: true
|
||||
on_success:
|
||||
- logger.log: Heading calibrated
|
||||
on_error:
|
||||
- logger.log: Heading calibration failed
|
||||
@@ -9,49 +9,6 @@ esphome:
|
||||
id: bq25186_charger
|
||||
battery_regulation_voltage: 4.1V
|
||||
fast_charge_current: 200mA
|
||||
- bq25186.apply_configuration:
|
||||
id: bq25186_charger
|
||||
charge_enabled: false
|
||||
flash_charging_mode: true
|
||||
precharge_is_iterm: true
|
||||
termination_percent: 5%
|
||||
vindpm_mode: 4.7v
|
||||
thermal_regulation: 80c
|
||||
battery_ocp_limit: 1500ma
|
||||
battery_uvlo: 3.0v
|
||||
mask_charge_status_interrupt: false
|
||||
mask_ilim_interrupt: false
|
||||
mask_vindpm_interrupt: true
|
||||
ts_auto_function: false
|
||||
vlowv: 2.8v
|
||||
recharge_threshold: 200mv
|
||||
double_timer_during_dpm: true
|
||||
safety_timer: 12h
|
||||
watchdog: 160s_hardware_reset
|
||||
long_press_duration: 15s
|
||||
hw_reset_requires_vin: true
|
||||
autowake: 2s
|
||||
input_current_limit: 200ma
|
||||
- bq25186.apply_configuration:
|
||||
id: bq25186_charger
|
||||
push_button_long_press_action: shutdown_mode
|
||||
wake1_timer: 1s
|
||||
wake2_timer: 3s
|
||||
enable_push_button: false
|
||||
system_regulation: 4.6v
|
||||
sys_mode: battery_only
|
||||
watchdog_15s_enable: false
|
||||
disable_vdppm: true
|
||||
ts_hot: 65c
|
||||
ts_cold: 3c
|
||||
ts_warm_disable: true
|
||||
ts_cool_disable: true
|
||||
ts_ichg: 0.2x
|
||||
ts_vrcg: -200mv
|
||||
mask_ts_interrupt: true
|
||||
mask_treg_interrupt: false
|
||||
mask_bat_interrupt: true
|
||||
mask_pg_interrupt: true
|
||||
|
||||
bq25186:
|
||||
- id: bq25186_charger
|
||||
|
||||
@@ -14,9 +14,6 @@ button:
|
||||
id: bms
|
||||
address: 0x09
|
||||
- bq76972.program_i2c_address: !lambda "return 0x08;"
|
||||
- bq76972.program_i2c_address:
|
||||
id: bms
|
||||
address: !lambda return 0x0A;
|
||||
|
||||
sensor:
|
||||
- platform: bq76972
|
||||
|
||||
@@ -69,7 +69,3 @@ button:
|
||||
- canbus.send: !lambda |-
|
||||
uint8_t val = (uint8_t)id(canbus_test_number).state;
|
||||
return std::vector<uint8_t>{0xAA, val, 0xBB};
|
||||
- canbus.send:
|
||||
can_id: 0x123
|
||||
remote_transmission_request: true
|
||||
data: []
|
||||
@@ -5,9 +5,6 @@ esphome:
|
||||
id: counter_sensor
|
||||
value: 100
|
||||
- counter.increment: counter_sensor
|
||||
- counter.set_value:
|
||||
id: counter_sensor
|
||||
value: !lambda return 42LL;
|
||||
- counter.increment:
|
||||
id: counter_sensor
|
||||
value: -5
|
||||
|
||||
@@ -14,8 +14,6 @@ esphome:
|
||||
then:
|
||||
- deep_sleep.enter:
|
||||
sleep_duration: 60min
|
||||
- deep_sleep.enter:
|
||||
sleep_duration: !lambda return 60000;
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return deep_sleep::woke_from_deep_sleep();'
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# (the default on ESP-IDF). Entering deep sleep runs the safe shutdown hooks,
|
||||
# where safe_mode confirms the running app image so the bootloader does not
|
||||
# roll back a fresh OTA update when the device goes to sleep before
|
||||
# boot_is_good_after has elapsed. The network this needs also serves the
|
||||
# deep_sleep.enter until/time_id case, which requires a time source.
|
||||
# boot_is_good_after has elapsed.
|
||||
substitutions:
|
||||
wakeup_pin: GPIO4
|
||||
|
||||
@@ -18,16 +17,3 @@ wifi:
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: "superlongpasswordthatnoonewillknow"
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: sntp_time
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: Sleep until
|
||||
on_press:
|
||||
- deep_sleep.enter:
|
||||
id: deep_sleep_1
|
||||
until: "06:30:00"
|
||||
time_id: sntp_time
|
||||
@@ -27,12 +27,6 @@ esphome:
|
||||
- dfplayer.set_volume: !lambda "return id(dfplayer_test).is_playing() ? 10 : 5;"
|
||||
- dfplayer.set_eq: ROCK
|
||||
- dfplayer.set_eq: !lambda "return id(dfplayer_test).is_playing() ? dfplayer::JAZZ : dfplayer::BASS;"
|
||||
- dfplayer.play_mp3:
|
||||
file: 7
|
||||
- dfplayer.set_volume:
|
||||
volume: 12
|
||||
- dfplayer.set_eq:
|
||||
eq_preset: CLASSIC
|
||||
- dfplayer.play_next
|
||||
- dfplayer.play_previous
|
||||
- dfplayer.reset
|
||||
|
||||
@@ -12,10 +12,6 @@ esphome:
|
||||
delay_after_detect: 0s
|
||||
delay_after_disappear: 0s
|
||||
sensitivity: 6
|
||||
- dfrobot_sen0395.settings:
|
||||
id: mmwave
|
||||
factory_reset: !lambda return false;
|
||||
sensitivity: !lambda return 7;
|
||||
- dfrobot_sen0395.reset
|
||||
|
||||
dfrobot_sen0395:
|
||||
|
||||
@@ -52,36 +52,6 @@ button:
|
||||
minute: !lambda return 45;
|
||||
- ds3231.set_alarm_2:
|
||||
mode: every_minute
|
||||
- ds3231.set_alarm_1:
|
||||
mode: weekly
|
||||
day_of_week: 3
|
||||
hour: !lambda return 8;
|
||||
second: !lambda return 30;
|
||||
enabled: !lambda return true;
|
||||
- ds3231.set_alarm_1:
|
||||
mode: monthly
|
||||
day_of_month: !lambda return 20;
|
||||
minute: !lambda return 10;
|
||||
- ds3231.set_alarm_2:
|
||||
mode: monthly
|
||||
day_of_month: 10
|
||||
enabled: false
|
||||
- ds3231.set_alarm_2:
|
||||
mode: weekly
|
||||
day_of_week: !lambda return 5;
|
||||
hour: !lambda return 18;
|
||||
- ds3231.enable_alarm:
|
||||
alarm: !lambda return 2;
|
||||
- ds3231.disable_alarm:
|
||||
alarm: !lambda return 1;
|
||||
- if:
|
||||
condition:
|
||||
ds3231.is_alarm_triggered:
|
||||
alarm: !lambda return 1;
|
||||
then:
|
||||
- logger.log: alarm 1 triggered
|
||||
- ds3231.set_32khz_output:
|
||||
state: !lambda return false;
|
||||
- ds3231.enable_alarm:
|
||||
alarm: 1
|
||||
- ds3231.disable_alarm:
|
||||
|
||||
@@ -3,8 +3,6 @@ esphome:
|
||||
then:
|
||||
- audio_adc.set_mic_gain: 0db
|
||||
- audio_adc.set_mic_gain: !lambda 'return 4;'
|
||||
- audio_adc.set_mic_gain:
|
||||
mic_gain: 6db
|
||||
|
||||
audio_adc:
|
||||
- platform: es7210
|
||||
|
||||
@@ -35,18 +35,6 @@ espnow:
|
||||
data: [0x01, 0x02, 0x03, 0x04, 0x05]
|
||||
- espnow.broadcast:
|
||||
data: !lambda 'return {0x01, 0x02, 0x03, 0x04, 0x05};'
|
||||
- espnow.broadcast:
|
||||
address: FF:FF:FF:FF:FF:FF
|
||||
data: "options"
|
||||
wait_for_sent: true
|
||||
continue_on_error: false
|
||||
on_sent:
|
||||
- logger.log: "broadcast sent"
|
||||
on_error:
|
||||
- logger.log: "broadcast failed"
|
||||
- espnow.send:
|
||||
address: !lambda 'return {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};'
|
||||
data: "lambda address"
|
||||
- espnow.send:
|
||||
address: 11:22:33:44:55:66
|
||||
data: !lambda 'return std::vector<uint8_t>(data, data + size);'
|
||||
|
||||
@@ -46,13 +46,6 @@ text_sensor:
|
||||
- ezo_pmp.set_calibration_volume:
|
||||
id: hcl_pump
|
||||
volume: 10
|
||||
- ezo_pmp.dose_with_constant_flow_rate:
|
||||
id: hcl_pump
|
||||
volume_per_minute: !lambda return 5.5f;
|
||||
duration: !lambda return 3;
|
||||
- ezo_pmp.set_calibration_volume:
|
||||
id: hcl_pump
|
||||
volume: !lambda return 12.5f;
|
||||
- ezo_pmp.find: hcl_pump
|
||||
- ezo_pmp.dose_continuously: hcl_pump
|
||||
- ezo_pmp.clear_total_volume_dosed: hcl_pump
|
||||
|
||||
@@ -14,10 +14,3 @@ button:
|
||||
speed: 200
|
||||
color: BLUE
|
||||
count: 2
|
||||
- fingerprint_grow.aura_led_control:
|
||||
state: !lambda return fingerprint_grow::FLASHING;
|
||||
speed: !lambda return 100;
|
||||
color: !lambda return fingerprint_grow::RED;
|
||||
count: !lambda return 3;
|
||||
- fingerprint_grow.delete:
|
||||
finger_id: !lambda return 2;
|
||||
@@ -9,9 +9,6 @@ hdmi_cec:
|
||||
- hdmi_cec.send:
|
||||
destination: !lambda return source;
|
||||
data: [0x90, 0x01] # Report Power Status: standby
|
||||
- hdmi_cec.send:
|
||||
destination: 0x0
|
||||
data: !lambda return {0x90, 0x01};
|
||||
- opcode: 0x8C # Give Device Vendor ID
|
||||
then:
|
||||
- lambda: |-
|
||||
|
||||
@@ -5,8 +5,6 @@ esphome:
|
||||
name: "Test"
|
||||
direction: 1
|
||||
- hlk_fm22x.delete: 5
|
||||
- hlk_fm22x.delete:
|
||||
face_id: 7
|
||||
- hlk_fm22x.delete_all:
|
||||
- hlk_fm22x.reset:
|
||||
- hlk_fm22x.scan:
|
||||
|
||||
@@ -35,59 +35,6 @@ esphome:
|
||||
- http_request.get:
|
||||
url: https://esphome.io
|
||||
timeout: !lambda "return 10000;"
|
||||
- http_request.get:
|
||||
url: !lambda 'return std::string("https://esphome.io/get");'
|
||||
method: GET
|
||||
collect_headers:
|
||||
- Content-Type
|
||||
- X-Request-Id
|
||||
max_response_buffer_size: 2kB
|
||||
capture_response: true
|
||||
on_response:
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Content-Type %s, body %zu bytes"
|
||||
args:
|
||||
- response->get_response_header("content-type").c_str()
|
||||
- body.size()
|
||||
- http_request.post:
|
||||
url: !lambda 'return std::string("https://esphome.io/post");'
|
||||
method: POST
|
||||
body: !lambda 'return std::string("{\"key\": \"value\"}");'
|
||||
timeout: 5s
|
||||
collect_headers:
|
||||
- Location
|
||||
max_response_buffer_size: 512
|
||||
on_error:
|
||||
- logger.log: "POST failed"
|
||||
- http_request.post:
|
||||
url: https://esphome.io
|
||||
body: "plain body"
|
||||
timeout: !lambda "return 2500;"
|
||||
- http_request.send:
|
||||
method: PATCH
|
||||
url: !lambda 'return std::string("https://esphome.io/send");'
|
||||
json:
|
||||
key: value
|
||||
dynamic: !lambda 'return std::string("x");'
|
||||
collect_headers:
|
||||
- ETag
|
||||
max_response_buffer_size: 4kB
|
||||
capture_response: true
|
||||
timeout: !lambda "return 3000;"
|
||||
on_response:
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Send status %d, body %s"
|
||||
args:
|
||||
- response->status_code
|
||||
- body.c_str()
|
||||
on_error:
|
||||
- logger.log: "Send failed"
|
||||
- http_request.send:
|
||||
method: DELETE
|
||||
url: https://esphome.io/item
|
||||
body: !lambda 'return std::string("id=1");'
|
||||
- http_request.post:
|
||||
url: https://esphome.io
|
||||
request_headers:
|
||||
|
||||
@@ -21,9 +21,3 @@ button:
|
||||
- htu21d.set_heater_level:
|
||||
id: htu21d_sensor
|
||||
level: 5
|
||||
- htu21d.set_heater:
|
||||
id: htu21d_sensor
|
||||
status: !lambda return false;
|
||||
- htu21d.set_heater_level:
|
||||
id: htu21d_sensor
|
||||
level: !lambda return 3;
|
||||
@@ -10,6 +10,3 @@ esphome:
|
||||
- hub75.set_brightness:
|
||||
id: my_hub75
|
||||
brightness: 50
|
||||
- hub75.set_brightness:
|
||||
id: my_hub75
|
||||
brightness: !lambda return 150;
|
||||
@@ -108,6 +108,3 @@ interval:
|
||||
id: m5epd_display
|
||||
mode: A2
|
||||
- it8951.update: m5epd_display
|
||||
- it8951.update:
|
||||
id: m5epd_display
|
||||
mode: !lambda return it8951::UPDATE_MODE_GL16;
|
||||
@@ -155,33 +155,6 @@ esphome:
|
||||
- light.turn_off:
|
||||
id: test_rgb_light
|
||||
transition_length: 300ms
|
||||
- light.turn_off:
|
||||
id: test_rgb_light
|
||||
state: false
|
||||
transition_length: !lambda return 200;
|
||||
- light.turn_on:
|
||||
id: test_rgb_light
|
||||
red: !lambda return 0.2f;
|
||||
green: !lambda return 0.4f;
|
||||
blue: !lambda return 0.6f;
|
||||
transition_length: !lambda return 350;
|
||||
- light.turn_on:
|
||||
id: test_cwww_light
|
||||
color_temperature: 300 mireds
|
||||
- light.turn_on:
|
||||
id: test_cwww_light
|
||||
color_temperature: !lambda return 250.0f;
|
||||
- light.control:
|
||||
id: test_rgbww_light
|
||||
cold_white: !lambda return 0.6f;
|
||||
warm_white: !lambda return 0.2f;
|
||||
- light.control:
|
||||
id: test_monochromatic_light
|
||||
effect: !lambda return "My Flicker";
|
||||
- light.dim_relative:
|
||||
id: test_monochromatic_light
|
||||
relative_brightness: !lambda return 0.1f;
|
||||
transition_length: !lambda return 150;
|
||||
# Test static effect name resolution at codegen time
|
||||
- light.turn_on:
|
||||
id: test_monochromatic_light
|
||||
|
||||
@@ -9,12 +9,5 @@ button:
|
||||
on_press:
|
||||
lightwaverf.send_raw:
|
||||
code: [0x04, 0x00, 0x00, 0x00, 0x0f, 0x03, 0x0d, 0x09, 0x08, 0x08]
|
||||
name: "Sofa"
|
||||
repeat: 1
|
||||
- platform: template
|
||||
name: "Turn off sofa inverted"
|
||||
on_press:
|
||||
lightwaverf.send_raw:
|
||||
code: [0x04, 0x00, 0x00, 0x00, 0x0f, 0x03, 0x0d, 0x09, 0x08, 0x08]
|
||||
name: "Sofa inverted"
|
||||
inverted: true
|
||||
pulse_length: 300
|
||||
@@ -5,10 +5,6 @@ esphome:
|
||||
level: warn
|
||||
format: "Warning: Logger level is %d"
|
||||
args: [id(logger_id).get_log_level()]
|
||||
- logger.log:
|
||||
tag: custom.tag
|
||||
level: info
|
||||
format: "Tagged log entry"
|
||||
- logger.set_level: WARN
|
||||
- logger.set_level:
|
||||
level: ERROR
|
||||
|
||||
@@ -41,10 +41,6 @@ script:
|
||||
id: test_list_id
|
||||
label:
|
||||
text: row
|
||||
- lvgl.list.add:
|
||||
id: test_list_id
|
||||
checkbox:
|
||||
text: list checkbox
|
||||
|
||||
esphome:
|
||||
on_boot:
|
||||
@@ -113,7 +109,6 @@ lvgl:
|
||||
end_value: 180
|
||||
- lvgl.indicator.update:
|
||||
id: meter_arc_indicator
|
||||
value: 90
|
||||
opa: 50%
|
||||
- lvgl.indicator.update:
|
||||
id: minute_hand
|
||||
@@ -125,14 +120,6 @@ lvgl:
|
||||
- anim_color
|
||||
duration: 3s
|
||||
loop: true
|
||||
- lvgl.animation.start:
|
||||
id: anim_slide
|
||||
start_delay: 250ms
|
||||
- lvgl.update:
|
||||
disp_bg_color: 0x101010
|
||||
disp_bg_opa: 80%
|
||||
- lvgl.update:
|
||||
disp_bg_image: cat_image
|
||||
on_invalidate_area:
|
||||
logger.log: Invalidate area
|
||||
on_resolution_change:
|
||||
@@ -704,11 +691,8 @@ lvgl:
|
||||
on_long_press:
|
||||
lvgl.matrix.button.update:
|
||||
id: [button_a, button_e, button_c]
|
||||
width: 2
|
||||
selected: true
|
||||
control:
|
||||
disabled: true
|
||||
checkable: true
|
||||
on_click:
|
||||
logger.log:
|
||||
format: "matrix button clicked: %d, is button_a = %u"
|
||||
@@ -1087,13 +1071,6 @@ lvgl:
|
||||
outline_width: 4
|
||||
outline_pad: 4
|
||||
outline_opa: cover
|
||||
- lvgl.canvas.draw_rectangle:
|
||||
x: 10
|
||||
y: 10
|
||||
width: !lambda return 120;
|
||||
height: !lambda return 80;
|
||||
shadow_ofs_x: 3
|
||||
shadow_ofs_y: 3
|
||||
- lvgl.canvas.set_pixels:
|
||||
color: red
|
||||
points:
|
||||
@@ -1127,12 +1104,6 @@ lvgl:
|
||||
text: Canvas Text
|
||||
align: center
|
||||
max_width: 150
|
||||
- lvgl.canvas.draw_text:
|
||||
x: 20
|
||||
y: 150
|
||||
font: montserrat_18
|
||||
text: Lambda Width
|
||||
max_width: !lambda return 120;
|
||||
- lvgl.canvas.draw_image:
|
||||
src: cat_image
|
||||
x: 100
|
||||
@@ -1144,20 +1115,6 @@ lvgl:
|
||||
skew_y: 5
|
||||
pivot_x: 25
|
||||
pivot_y: 25
|
||||
- lvgl.canvas.draw_image:
|
||||
src: cat_image
|
||||
x: 50
|
||||
y: 50
|
||||
angle: 45
|
||||
scale: 1.5
|
||||
opa: 70%
|
||||
recolor: red
|
||||
recolor_opa: 30%
|
||||
- lvgl.canvas.draw_image:
|
||||
src: cat_image
|
||||
x: 60
|
||||
y: 60
|
||||
zoom: 2.0
|
||||
- lvgl.canvas.draw_rectangle:
|
||||
x: 10
|
||||
y: 10
|
||||
@@ -1396,12 +1353,6 @@ lvgl:
|
||||
column: 1
|
||||
text: !lambda return str_sprintf("%.1f", (float) rand() / RAND_MAX * 100);
|
||||
merge_right: false
|
||||
- lvgl.table.cell.update:
|
||||
id: table_id
|
||||
row: 0
|
||||
column: 1
|
||||
text: cropped
|
||||
text_crop: true
|
||||
- lvgl.table.update:
|
||||
id: table_id
|
||||
selected_row: !lambda return (int) ((float) rand() / RAND_MAX * 2);
|
||||
@@ -1433,9 +1384,6 @@ lvgl:
|
||||
- 180, 60
|
||||
- 240, 10
|
||||
- lvgl.page.next:
|
||||
- lvgl.page.next:
|
||||
animation: move_left
|
||||
time: 200ms
|
||||
- switch:
|
||||
align: right_mid
|
||||
- checkbox:
|
||||
|
||||
@@ -75,8 +75,6 @@ lvgl:
|
||||
on_draw_end:
|
||||
- logger.log: draw ended
|
||||
- lvgl.pause:
|
||||
- lvgl.pause:
|
||||
show_snow: true
|
||||
- component.update: tft_display
|
||||
- delay: 60s
|
||||
- lvgl.resume:
|
||||
@@ -20,6 +20,3 @@ esphome:
|
||||
- max7219digit.reverse_on:
|
||||
- max7219digit.reverse_off:
|
||||
- max7219digit.intensity: 10
|
||||
- max7219digit.intensity:
|
||||
intensity: 7
|
||||
- max7219digit.intensity: !lambda return 3;
|
||||
@@ -53,60 +53,6 @@ media_player:
|
||||
- media_player.unshuffle: test_media_player
|
||||
- media_player.group_join: test_media_player
|
||||
- media_player.clear_playlist: test_media_player
|
||||
- media_player.play:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.pause:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.toggle:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.turn_on:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.turn_off:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.next:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.previous:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.mute:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.unmute:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.repeat_off:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.repeat_one:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.repeat_all:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.shuffle:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.unshuffle:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.group_join:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.clear_playlist:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.volume_up:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- media_player.volume_down:
|
||||
id: test_media_player
|
||||
announcement: true
|
||||
- wait_until:
|
||||
media_player.is_idle: test_media_player
|
||||
- wait_until:
|
||||
@@ -140,7 +86,3 @@ media_player:
|
||||
id: test_media_player
|
||||
media_url: http://localhost/media.mp3
|
||||
announcement: true
|
||||
- media_player.enqueue:
|
||||
id: test_media_player
|
||||
media_url: http://localhost/media.mp3
|
||||
announcement: !lambda return true;
|
||||
@@ -10,10 +10,6 @@ button:
|
||||
id: midea_unit
|
||||
temperature: !lambda return id(midea_unit).target_temperature + 1.0f;
|
||||
use_fahrenheit: !lambda return false;
|
||||
- midea_ac.follow_me:
|
||||
id: midea_unit
|
||||
temperature: 24.0
|
||||
beeper: !lambda return true;
|
||||
- midea_ac.display_toggle:
|
||||
id: midea_unit
|
||||
- midea_ac.swing_step:
|
||||
|
||||
@@ -30,9 +30,6 @@ esphome:
|
||||
temperature: 22.0
|
||||
- mitsubishi_cn105.clear_remote_temperature:
|
||||
id: ac
|
||||
- mitsubishi_cn105.set_remote_temperature:
|
||||
id: ac
|
||||
temperature: !lambda return 21.5f;
|
||||
- mitsubishi_cn105.vane.control:
|
||||
id: ac
|
||||
vertical:
|
||||
|
||||
@@ -186,215 +186,6 @@ button:
|
||||
read_address: 0x0420
|
||||
read_count: 1
|
||||
|
||||
- platform: template
|
||||
name: "Typed Handlers"
|
||||
on_press:
|
||||
- modbus_client.read_coils:
|
||||
address: !lambda "return 1;"
|
||||
start_address: !lambda "return 0x03;"
|
||||
count: !lambda "return 8;"
|
||||
continuous: !lambda "return false;"
|
||||
allow_broadcast_read: !lambda "return false;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "coils sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "coils not sent fc 0x%X", request.empty() ? 0 : request[0]);'
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "coils timeout"
|
||||
retry: !lambda "return false;"
|
||||
on_custom_response:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "coils custom reply %u bytes", (unsigned) response.size());'
|
||||
- modbus_client.read_coils:
|
||||
address: 0
|
||||
start_address: 0x03
|
||||
allow_broadcast_read: true
|
||||
on_response:
|
||||
then:
|
||||
- lambda: 'ESP_LOGI("modbus_client.test", "broadcast coil0=%d", bits[0]);'
|
||||
- modbus_client.read_discrete_inputs:
|
||||
address: !lambda "return 1;"
|
||||
start_address: !lambda "return 0x00;"
|
||||
count: 4
|
||||
continuous: !lambda "return true;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "inputs sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "inputs not sent"
|
||||
on_no_response: !lambda "return false;"
|
||||
on_response:
|
||||
then:
|
||||
- lambda: 'ESP_LOGI("modbus_client.test", "input0=%d n=%u", bits[0], (unsigned) bits.size());'
|
||||
on_custom_response:
|
||||
then:
|
||||
- logger.log: "inputs custom reply"
|
||||
- modbus_client.read_discrete_inputs:
|
||||
address: 0
|
||||
start_address: 0x00
|
||||
allow_broadcast_read: true
|
||||
- modbus_client.read_holding_registers:
|
||||
address: 0x01
|
||||
start_address: !lambda "return 0x10;"
|
||||
continuous: !lambda "return true;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "holding sent"
|
||||
on_custom_response:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "holding custom reply fc 0x%X", response.empty() ? 0 : response[0]);'
|
||||
- modbus_client.read_input_registers:
|
||||
address: !lambda "return 1;"
|
||||
start_address: !lambda "return 0x20;"
|
||||
count: 3
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "inputs regs sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "input regs not sent"
|
||||
on_error:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "input regs exception %d", (int) exception_code);'
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "input regs timeout"
|
||||
on_response:
|
||||
then:
|
||||
- lambda: 'ESP_LOGI("modbus_client.test", "input reg0=%u n=%u", values[0], (unsigned) values.size());'
|
||||
- modbus_client.read_input_registers:
|
||||
address: 0
|
||||
start_address: 0x20
|
||||
allow_broadcast_read: true
|
||||
- modbus_client.read_write_multiple_registers:
|
||||
address: !lambda "return 1;"
|
||||
write_address: !lambda "return 0x0300;"
|
||||
values: [1, 2]
|
||||
read_address: !lambda "return 0x0400;"
|
||||
read_count: !lambda "return 2;"
|
||||
allow_broadcast_read: !lambda "return false;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "rw sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "rw not sent"
|
||||
on_error:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "rw exception %d", (int) exception_code);'
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "rw timeout"
|
||||
on_custom_response:
|
||||
then:
|
||||
- logger.log: "rw custom reply"
|
||||
- modbus_client.send:
|
||||
address: 0
|
||||
pdu: [0x03, 0x00, 0x10, 0x00, 0x01]
|
||||
allow_broadcast_read: true
|
||||
- modbus_client.send:
|
||||
address: !lambda "return 1;"
|
||||
pdu: [0x06, 0x01, 0x02, 0x00, 0x2A]
|
||||
continuous: !lambda "return false;"
|
||||
expect_broadcast_write_response: !lambda "return false;"
|
||||
- modbus_client.write_multiple_coils:
|
||||
address: !lambda "return 1;"
|
||||
start_address: !lambda "return 0x0010;"
|
||||
values: [true, false]
|
||||
expect_broadcast_write_response: !lambda "return false;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "coils write sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "coils write not sent"
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "coils write timeout"
|
||||
on_response:
|
||||
then:
|
||||
- logger.log: "coils write acked"
|
||||
on_custom_response:
|
||||
then:
|
||||
- logger.log: "coils write custom reply"
|
||||
- modbus_client.write_multiple_coils:
|
||||
address: 0
|
||||
start_address: 0x0010
|
||||
values: [true]
|
||||
expect_broadcast_write_response: true
|
||||
- modbus_client.write_multiple_registers:
|
||||
address: !lambda "return 1;"
|
||||
start_address: !lambda "return 0x0200;"
|
||||
values: [1, 2]
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "regs write sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "regs write not sent"
|
||||
on_error:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "regs write exception %d", (int) exception_code);'
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "regs write timeout"
|
||||
on_custom_response:
|
||||
then:
|
||||
- logger.log: "regs write custom reply"
|
||||
- modbus_client.write_multiple_registers:
|
||||
address: 0
|
||||
start_address: 0x0200
|
||||
values: [7]
|
||||
expect_broadcast_write_response: true
|
||||
- modbus_client.write_single_coil:
|
||||
address: !lambda "return 1;"
|
||||
start_address: !lambda "return 0x01;"
|
||||
value: !lambda "return false;"
|
||||
expect_broadcast_write_response: !lambda "return false;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "coil sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "coil not sent"
|
||||
on_error:
|
||||
then:
|
||||
- lambda: 'ESP_LOGW("modbus_client.test", "coil exception %d", (int) exception_code);'
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "coil timeout"
|
||||
on_response:
|
||||
then:
|
||||
- logger.log: "coil acked"
|
||||
on_custom_response:
|
||||
then:
|
||||
- logger.log: "coil custom reply"
|
||||
- modbus_client.write_single_coil:
|
||||
address: 0
|
||||
start_address: 0x01
|
||||
value: true
|
||||
expect_broadcast_write_response: true
|
||||
- modbus_client.write_single_register:
|
||||
address: 0x01
|
||||
start_address: !lambda "return 0x0102;"
|
||||
value: 42
|
||||
expect_broadcast_write_response: !lambda "return false;"
|
||||
on_sent:
|
||||
then:
|
||||
- logger.log: "register sent"
|
||||
on_not_sent:
|
||||
then:
|
||||
- logger.log: "register not sent"
|
||||
on_no_response:
|
||||
then:
|
||||
- logger.log: "register timeout"
|
||||
on_custom_response:
|
||||
then:
|
||||
- logger.log: "register custom reply"
|
||||
number:
|
||||
- platform: template
|
||||
name: "Modbus Client Write Value"
|
||||
|
||||
@@ -8,9 +8,7 @@ esphome:
|
||||
condition:
|
||||
modem.enabled:
|
||||
then:
|
||||
- modem.send_at: "AT+CGSN"
|
||||
- modem.send_at:
|
||||
command: !lambda 'return std::string("AT+CSQ");'
|
||||
modem.send_at: "AT+CGSN"
|
||||
else:
|
||||
modem.enable:
|
||||
- if:
|
||||
|
||||
@@ -109,18 +109,6 @@ button:
|
||||
return payload;
|
||||
qos: !lambda return 1;
|
||||
retain: !lambda return false;
|
||||
- mqtt.publish_json:
|
||||
topic: some/topic/json
|
||||
payload: |-
|
||||
root["key"] = "value";
|
||||
qos: 1
|
||||
retain: true
|
||||
- mqtt.publish_json:
|
||||
topic: !lambda return "some/topic/json/lambda";
|
||||
payload: |-
|
||||
root["key"] = 1;
|
||||
qos: !lambda return 2;
|
||||
retain: !lambda return false;
|
||||
|
||||
climate:
|
||||
- platform: thermostat
|
||||
|
||||
@@ -42,19 +42,6 @@ button:
|
||||
cycle: false
|
||||
- number.to_min: number_test_number
|
||||
- number.to_max: number_test_number
|
||||
- number.increment:
|
||||
id: number_test_number
|
||||
mode: INCREMENT
|
||||
cycle: true
|
||||
- number.decrement:
|
||||
id: number_test_number
|
||||
mode: DECREMENT
|
||||
- number.to_min:
|
||||
id: number_test_number
|
||||
mode: TO_MIN
|
||||
- number.to_max:
|
||||
id: number_test_number
|
||||
mode: TO_MAX
|
||||
- number.operation:
|
||||
id: number_test_number
|
||||
operation: increment
|
||||
|
||||
@@ -18,5 +18,3 @@ switch:
|
||||
turn_off_action:
|
||||
then:
|
||||
- openthread.set_poll_period: 5s
|
||||
- openthread.set_poll_period:
|
||||
poll_period: !lambda return 10000;
|
||||
@@ -15,12 +15,6 @@ esphome:
|
||||
- output.set_max_power:
|
||||
id: output_light_output_1
|
||||
max_power: 80%
|
||||
- output.set_min_power:
|
||||
id: output_light_output_1
|
||||
min_power: !lambda return 0.1f;
|
||||
- output.set_max_power:
|
||||
id: output_light_output_1
|
||||
max_power: !lambda return 0.9f;
|
||||
|
||||
output:
|
||||
- platform: ${output_platform}
|
||||
|
||||
@@ -11,11 +11,6 @@ esphome:
|
||||
- tag.set_emulation_message:
|
||||
message: https://www.home-assistant.io/tag/pulse
|
||||
include_android_app_record: false
|
||||
- tag.set_write_message:
|
||||
message: !lambda return std::string("https://www.home-assistant.io/tag/lambda");
|
||||
- tag.set_emulation_message:
|
||||
message: !lambda return std::string("https://www.home-assistant.io/tag/lambda");
|
||||
include_android_app_record: true
|
||||
- tag.emulation_off: nfcc_pn7150
|
||||
- tag.emulation_on: nfcc_pn7150
|
||||
- tag.polling_off: nfcc_pn7150
|
||||
|
||||
@@ -564,482 +564,3 @@ button:
|
||||
on_press:
|
||||
- remote_transmitter.transmit_pd_pioneer:
|
||||
code: [0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x80]
|
||||
- platform: template
|
||||
name: Repeat on every protocol
|
||||
on_press:
|
||||
- remote_transmitter.transmit_abbwelcome:
|
||||
source_address: 0x1234
|
||||
destination_address: 0x5678
|
||||
message_type: 0x01
|
||||
data: [0x10]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_aeha:
|
||||
address: 0x8008
|
||||
data: [0x00, 0x02]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_beo4:
|
||||
source: 0x01
|
||||
command: 0x0C
|
||||
command_repeats: 3
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_brennenstuhl:
|
||||
code: 0xBD2E2C
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_byronsx:
|
||||
address: 0x12
|
||||
command: 0x05
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_canalsat:
|
||||
device: 0x25
|
||||
address: 0x01
|
||||
command: 0x1C
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_canalsatld:
|
||||
device: 0x25
|
||||
address: 0x02
|
||||
command: 0x1C
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_coolix:
|
||||
first: 0xB2BF40
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_dish:
|
||||
address: 1
|
||||
command: 16
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_dooya:
|
||||
id: 0x123456
|
||||
channel: 1
|
||||
button: 1
|
||||
check: 1
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_drayton:
|
||||
address: 0x1234
|
||||
channel: 0x01
|
||||
command: 0x05
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_dyson:
|
||||
code: 0x1215
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_gobox:
|
||||
code: 1
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_haier:
|
||||
code: [0xA6, 0xDA, 0x00, 0x00, 0x40, 0x40, 0x00, 0x80]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_hob2hood:
|
||||
command: fan_low
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_ira211:
|
||||
command: power
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_jvc:
|
||||
data: 0x10EF
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_keeloq:
|
||||
address: 0x57ffe7b
|
||||
command: 0x02
|
||||
code: 0xd19ef0a9
|
||||
level: true
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_lg:
|
||||
data: 0x20DF10EF
|
||||
nbits: 32
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_magiquest:
|
||||
wand_id: 0x01234567
|
||||
magnitude: 0x1234
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_midea:
|
||||
code: [0xA2, 0x08, 0xFF, 0xFF, 0xFF]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_mirage:
|
||||
code: [0x56, 0x77, 0x00, 0x00, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_nec:
|
||||
address: 0x4242
|
||||
command: 0x8484
|
||||
command_repeats: 3
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_nexa:
|
||||
device: 0x38DDB5A
|
||||
group: 0
|
||||
state: 1
|
||||
channel: 15
|
||||
level: 0
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_nexus:
|
||||
channel: 1
|
||||
address: 0x42
|
||||
temperature: 21.5
|
||||
humidity: 50
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_onkyori:
|
||||
data: 0xD9
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_panasonic:
|
||||
address: 0x4004
|
||||
command: 0x1000BCD
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_pd_pioneer:
|
||||
code: [0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x80]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_pioneer_wyt:
|
||||
code: [0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x80]
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_pronto:
|
||||
data: "0000 006D 0001 0000 0015 0016"
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_raw:
|
||||
code: [1000, -1000]
|
||||
carrier_frequency: 38kHz
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc5:
|
||||
address: 0x00
|
||||
command: 0x0B
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc5x:
|
||||
address: 0x10
|
||||
command: 0x0
|
||||
extension: 0x6
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc6:
|
||||
address: 0x00
|
||||
command: 0x0C
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc_switch_raw:
|
||||
code: "001010011001111101010000"
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc_switch_type_a:
|
||||
group: "11001"
|
||||
device: "01000"
|
||||
state: true
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc_switch_type_b:
|
||||
address: 4
|
||||
channel: 2
|
||||
state: true
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc_switch_type_c:
|
||||
family: "a"
|
||||
group: 1
|
||||
device: 2
|
||||
state: true
|
||||
protocol: 2
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_rc_switch_type_d:
|
||||
group: "a"
|
||||
device: 2
|
||||
state: true
|
||||
protocol:
|
||||
pulse_length: 350
|
||||
sync: [1, 31]
|
||||
zero: [1, 3]
|
||||
one: [3, 1]
|
||||
inverted: true
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_roomba:
|
||||
data: 0x88
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_samsung:
|
||||
data: 0xABCDEF0123
|
||||
nbits: 40
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_samsung36:
|
||||
address: 0x0400
|
||||
command: 0x000E00FF
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_sony:
|
||||
data: 0xABCDEF
|
||||
nbits: 12
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_symphony:
|
||||
data: 0xE88
|
||||
nbits: 12
|
||||
command_repeats: 4
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_toshiba_ac:
|
||||
rc_code_1: 0xB24DBF4050AF
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 10ms
|
||||
- remote_transmitter.transmit_jvc:
|
||||
data: 0x10EF
|
||||
repeat: 3
|
||||
- remote_transmitter.transmit_nec:
|
||||
address: 0x4242
|
||||
command: 0x8484
|
||||
repeat:
|
||||
times: !lambda return 2;
|
||||
wait_time: !lambda return 10000;
|
||||
- platform: template
|
||||
name: Lambda fields on every protocol
|
||||
on_press:
|
||||
- remote_transmitter.transmit_abbwelcome:
|
||||
source_address: !lambda return 0x1234;
|
||||
destination_address: !lambda return 0x5678;
|
||||
three_byte_address: !lambda return false;
|
||||
retransmission: !lambda return true;
|
||||
message_type: !lambda return 0x01;
|
||||
message_id: !lambda return 0x42;
|
||||
data: [0x10, 0x20]
|
||||
- remote_transmitter.transmit_aeha:
|
||||
address: !lambda return 0x8008;
|
||||
carrier_frequency: !lambda return 38000;
|
||||
data: [0x00, 0x02]
|
||||
- remote_transmitter.transmit_aok:
|
||||
remote_id: !lambda return 0x123456;
|
||||
channels: 0x00A1
|
||||
command: !lambda return 0x0B;
|
||||
- remote_transmitter.transmit_beo4:
|
||||
source: !lambda return 0x01;
|
||||
command: !lambda return 0x0C;
|
||||
command_repeats: !lambda return 2;
|
||||
- remote_transmitter.transmit_brennenstuhl:
|
||||
code: !lambda return 0xBD2E2C;
|
||||
- remote_transmitter.transmit_byronsx:
|
||||
address: !lambda return 0x12;
|
||||
command: !lambda return 0x05;
|
||||
- remote_transmitter.transmit_canalsat:
|
||||
device: !lambda return 0x25;
|
||||
address: !lambda return 0x01;
|
||||
command: !lambda return 0x1C;
|
||||
- remote_transmitter.transmit_canalsatld:
|
||||
device: !lambda return 0x25;
|
||||
address: !lambda return 0x01;
|
||||
command: 0x1C
|
||||
- remote_transmitter.transmit_coolix:
|
||||
first: !lambda return 0xB2BF40;
|
||||
second: !lambda return 0xB2BF40;
|
||||
- remote_transmitter.transmit_dish:
|
||||
address: !lambda return 1;
|
||||
command: !lambda return 16;
|
||||
- remote_transmitter.transmit_dooya:
|
||||
id: !lambda return 0x123456;
|
||||
channel: !lambda return 1;
|
||||
button: !lambda return 1;
|
||||
check: !lambda return 1;
|
||||
- remote_transmitter.transmit_drayton:
|
||||
address: !lambda return 0x1230;
|
||||
data: !lambda return 0x8;
|
||||
- remote_transmitter.transmit_drayton:
|
||||
address: 0x1234
|
||||
channel: !lambda return 0x01;
|
||||
command: !lambda return 0x05;
|
||||
- remote_transmitter.transmit_dyson:
|
||||
code: !lambda return 0x1215;
|
||||
index: !lambda return 0x0;
|
||||
- remote_transmitter.transmit_gobox:
|
||||
code: !lambda return 1;
|
||||
- remote_transmitter.transmit_hob2hood:
|
||||
command: !lambda return remote_base::HOB2HOOD_COMMAND_FAN_HIGH;
|
||||
- remote_transmitter.transmit_ira211:
|
||||
command: !lambda return remote_base::IRA211Command::IRA211_COMMAND_POWER;
|
||||
temperature: !lambda return 21.5;
|
||||
mode: !lambda return remote_base::IRA211Mode::IRA211_MODE_TIMER;
|
||||
fan_mode: !lambda return remote_base::IRA211Fan::IRA211_FAN_LOW;
|
||||
- remote_transmitter.transmit_jvc:
|
||||
data: !lambda return 0x10EF;
|
||||
- remote_transmitter.transmit_keeloq:
|
||||
address: 0x57ffe7b
|
||||
command: !lambda return 0x02;
|
||||
code: !lambda return 0xd19ef0a9;
|
||||
level: !lambda return true;
|
||||
- remote_transmitter.transmit_keeloq:
|
||||
address: 0x1234500
|
||||
command: 0x8
|
||||
code: 0xF94A09F2
|
||||
group: !lambda return 0x0F;
|
||||
- remote_transmitter.transmit_keeloq:
|
||||
address: 0x116ea01
|
||||
command: 0x08
|
||||
code: 0xd19ef0a9
|
||||
suffix: !lambda return 0x00;
|
||||
suffix_bits: !lambda return 8;
|
||||
- remote_transmitter.transmit_lg:
|
||||
data: !lambda return 0xFFFFFFFF;
|
||||
nbits: !lambda return 28;
|
||||
- remote_transmitter.transmit_magiquest:
|
||||
wand_id: !lambda return 0x01234567;
|
||||
magnitude: !lambda return 0xFFFF;
|
||||
- remote_transmitter.transmit_nec:
|
||||
address: !lambda return 0x4242;
|
||||
command: !lambda return 0x8484;
|
||||
command_repeats: !lambda return 1;
|
||||
- remote_transmitter.transmit_nexa:
|
||||
device: !lambda return 0x38DDB5A;
|
||||
group: !lambda return 0;
|
||||
state: !lambda return 1;
|
||||
channel: !lambda return 15;
|
||||
level: !lambda return 0;
|
||||
- remote_transmitter.transmit_nexus:
|
||||
channel: !lambda return 1;
|
||||
address: !lambda return 0x42;
|
||||
temperature: !lambda return -12.3f;
|
||||
humidity: !lambda return 69;
|
||||
battery_level: !lambda return false;
|
||||
force_update: !lambda return true;
|
||||
- remote_transmitter.transmit_onkyori:
|
||||
data: !lambda return 0xD9;
|
||||
- remote_transmitter.transmit_panasonic:
|
||||
nbits: !lambda return 56;
|
||||
address: !lambda return 0x4004;
|
||||
address_2: !lambda return 0x12;
|
||||
command: 0x1000BCD
|
||||
carrier_frequency: !lambda return 36000;
|
||||
- remote_transmitter.transmit_pd_pioneer:
|
||||
code: !lambda return {0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x80};
|
||||
- remote_transmitter.transmit_pioneer:
|
||||
rc_code_1: !lambda return 0xA556;
|
||||
rc_code_2: !lambda return 0xA506;
|
||||
- remote_transmitter.transmit_pioneer_wyt:
|
||||
code: !lambda return {0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x80};
|
||||
- remote_transmitter.transmit_pronto:
|
||||
data: !lambda return std::string("0000 006D 0001 0000 0015 0016");
|
||||
- remote_transmitter.transmit_rc5:
|
||||
address: !lambda return 0x00;
|
||||
command: !lambda return 0x0B;
|
||||
- remote_transmitter.transmit_rc5x:
|
||||
address: !lambda return 0x10;
|
||||
command: !lambda return 0x0;
|
||||
extension: !lambda return 0x6;
|
||||
- remote_transmitter.transmit_rc6:
|
||||
address: !lambda return 0x00;
|
||||
command: 0x0C
|
||||
- remote_transmitter.transmit_rc_switch_raw:
|
||||
code: !lambda return std::string("001010011001111101010000");
|
||||
- remote_transmitter.transmit_rc_switch_type_a:
|
||||
group: !lambda return std::string("11001");
|
||||
device: !lambda return std::string("01000");
|
||||
state: !lambda return true;
|
||||
- remote_transmitter.transmit_rc_switch_type_b:
|
||||
address: !lambda return 4;
|
||||
channel: !lambda return 2;
|
||||
state: !lambda return false;
|
||||
- remote_transmitter.transmit_rc_switch_type_c:
|
||||
family: !lambda return std::string("a");
|
||||
group: !lambda return 1;
|
||||
device: !lambda return 2;
|
||||
state: !lambda return true;
|
||||
- remote_transmitter.transmit_rc_switch_type_d:
|
||||
group: !lambda return std::string("a");
|
||||
device: !lambda return 2;
|
||||
state: !lambda return true;
|
||||
- remote_transmitter.transmit_roomba:
|
||||
data: !lambda return 0x88;
|
||||
- remote_transmitter.transmit_samsung:
|
||||
data: !lambda return 0xABCDEF;
|
||||
nbits: !lambda return 32;
|
||||
- remote_transmitter.transmit_samsung36:
|
||||
address: !lambda return 0x0400;
|
||||
command: !lambda return 0x000E00FF;
|
||||
- remote_transmitter.transmit_somfy_rts:
|
||||
address: !lambda return 0x630139;
|
||||
control: !lambda return 0x08;
|
||||
key: !lambda return 0xA0;
|
||||
rolling_code: 1234
|
||||
control_in_key: !lambda return false;
|
||||
- remote_transmitter.transmit_sony:
|
||||
data: !lambda return 0xABCDEF;
|
||||
nbits: !lambda return 15;
|
||||
- remote_transmitter.transmit_symphony:
|
||||
data: !lambda return 0xE88;
|
||||
nbits: !lambda return 12;
|
||||
command_repeats: !lambda return 2;
|
||||
- remote_transmitter.transmit_toshiba_ac:
|
||||
rc_code_1: !lambda return 0xB24DBF4050AF;
|
||||
rc_code_2: !lambda return 0xD5660001003C;
|
||||
- remote_transmitter.transmit_toto:
|
||||
command: !lambda return 0xEC;
|
||||
rc_code_1: !lambda return 0x0D;
|
||||
rc_code_2: !lambda return 0x0D;
|
||||
- remote_transmitter.transmit_raw:
|
||||
code: [1000, -1000]
|
||||
carrier_frequency: !lambda return 38000;
|
||||
@@ -12,11 +12,6 @@ rf_bridge:
|
||||
high: 0x1234
|
||||
code: 0x123456
|
||||
- rf_bridge.learn
|
||||
- rf_bridge.send_code:
|
||||
sync: !lambda return 0x1234;
|
||||
low: !lambda return 0x1234;
|
||||
high: !lambda return 0x1234;
|
||||
code: !lambda return 0x123456;
|
||||
on_advanced_code_received:
|
||||
- lambda: |-
|
||||
uint32_t test;
|
||||
@@ -32,12 +27,6 @@ rf_bridge:
|
||||
code: "ABC123"
|
||||
- rf_bridge.send_raw:
|
||||
raw: "AAA5070008001000ABC12355"
|
||||
- rf_bridge.send_advanced_code:
|
||||
length: !lambda return 0x04;
|
||||
protocol: !lambda return 0x01;
|
||||
code: !lambda return std::string("ABC123");
|
||||
- rf_bridge.send_raw:
|
||||
raw: !lambda return std::string("AAA5070008001000ABC12355");
|
||||
- rf_bridge.start_bucket_sniffing:
|
||||
- rf_bridge.beep:
|
||||
duration: !lambda return 100;
|
||||
@@ -21,14 +21,6 @@ esphome:
|
||||
- rx8111.schedule_alarm_in:
|
||||
id: rtc
|
||||
duration: !lambda return uint32_t{60};
|
||||
- rx8111.set_alarm:
|
||||
id: rtc
|
||||
second: !lambda return uint16_t{30};
|
||||
hour: !lambda return uint16_t{6};
|
||||
weekday: !lambda return uint16_t{3};
|
||||
- rx8111.set_alarm:
|
||||
id: rtc
|
||||
day: !lambda return uint16_t{20};
|
||||
- rx8111.clear_alarm_flag: rtc
|
||||
- rx8111.clear_timer_flag: rtc
|
||||
- rx8111.clear_event_flag: rtc
|
||||
|
||||
@@ -29,28 +29,6 @@ esphome:
|
||||
then:
|
||||
- logger.log: a script is running
|
||||
- script.execute: my_script_stops_itself
|
||||
- delay:
|
||||
minutes: 1
|
||||
seconds: 2
|
||||
milliseconds: 3
|
||||
- delay:
|
||||
hours: 1
|
||||
- if:
|
||||
all:
|
||||
- script.is_running: my_script
|
||||
- lambda: return true;
|
||||
then:
|
||||
- logger.log: all conditions true
|
||||
- wait_until:
|
||||
condition:
|
||||
not:
|
||||
script.is_running: my_script
|
||||
timeout: !lambda return 2000;
|
||||
- wait_until:
|
||||
condition:
|
||||
not:
|
||||
script.is_running: my_script
|
||||
timeout: 500ms
|
||||
- choose:
|
||||
- if:
|
||||
script.is_running: my_script
|
||||
|
||||
@@ -21,7 +21,3 @@ button:
|
||||
name: seeed_multi_channel_relay change address
|
||||
on_press:
|
||||
- seeed_multi_channel_relay.change_address: 0x12
|
||||
- seeed_multi_channel_relay.change_address:
|
||||
address: 0x13
|
||||
- seeed_multi_channel_relay.change_address:
|
||||
address: !lambda return 0x14;
|
||||
@@ -37,19 +37,6 @@ button:
|
||||
cycle: false
|
||||
- select.first: select_test_select
|
||||
- select.last: select_test_select
|
||||
- select.next:
|
||||
id: select_test_select
|
||||
mode: NEXT
|
||||
cycle: true
|
||||
- select.previous:
|
||||
id: select_test_select
|
||||
mode: PREVIOUS
|
||||
- select.first:
|
||||
id: select_test_select
|
||||
mode: FIRST
|
||||
- select.last:
|
||||
id: select_test_select
|
||||
mode: LAST
|
||||
- if:
|
||||
condition:
|
||||
select.is:
|
||||
|
||||
@@ -10,13 +10,6 @@ esphome:
|
||||
- sim800l.disconnect
|
||||
- sim800l.send_ussd:
|
||||
ussd: test_ussd
|
||||
- sim800l.send_sms:
|
||||
recipient: !lambda return std::string("+15550000000");
|
||||
message: !lambda return std::string("Lambda message");
|
||||
- sim800l.dial:
|
||||
recipient: !lambda return std::string("+15550000001");
|
||||
- sim800l.send_ussd:
|
||||
ussd: !lambda return std::string("*100#");
|
||||
|
||||
sim800l:
|
||||
on_sms_received:
|
||||
|
||||
@@ -57,10 +57,6 @@ media_player:
|
||||
id: media_player_id
|
||||
pipeline: media
|
||||
delay: 500ms
|
||||
- speaker_source.set_playlist_delay:
|
||||
id: media_player_id
|
||||
pipeline: announcement
|
||||
delay: !lambda return 250;
|
||||
- speaker_source.set_announcement_volume:
|
||||
id: media_player_id
|
||||
volume: !lambda return x;
|
||||
@@ -43,16 +43,6 @@ esphome:
|
||||
id: yard_sprinkler_ctrlr
|
||||
valve_number: !lambda return 1;
|
||||
run_duration: !lambda return 120;
|
||||
- sprinkler.set_divider:
|
||||
id: yard_sprinkler_ctrlr
|
||||
divider: !lambda return 3;
|
||||
- sprinkler.set_repeat:
|
||||
id: yard_sprinkler_ctrlr
|
||||
repeat: !lambda return 1;
|
||||
- sprinkler.start_single_valve:
|
||||
id: yard_sprinkler_ctrlr
|
||||
valve_number: !lambda return 1;
|
||||
run_duration: !lambda return 240;
|
||||
|
||||
switch:
|
||||
- platform: template
|
||||
|
||||
@@ -34,12 +34,3 @@ switch:
|
||||
- stepper.set_deceleration:
|
||||
id: test_stepper
|
||||
deceleration: 250 steps/s^2
|
||||
- stepper.report_position:
|
||||
id: test_stepper
|
||||
position: !lambda return 100;
|
||||
- stepper.set_speed:
|
||||
id: test_stepper
|
||||
speed: !lambda return 200.0f;
|
||||
- stepper.set_deceleration:
|
||||
id: test_stepper
|
||||
deceleration: !lambda return 180.0f;
|
||||
@@ -19,9 +19,3 @@ button:
|
||||
elevation: !lambda return 10.0;
|
||||
then:
|
||||
- logger.log: High sun
|
||||
- if:
|
||||
condition:
|
||||
sun.is_below_horizon:
|
||||
elevation: !lambda return -12.0;
|
||||
then:
|
||||
- logger.log: Deep night
|
||||
@@ -25,12 +25,6 @@ esphome:
|
||||
vol_range_min: 0.2
|
||||
vol_range_max: 0.9
|
||||
channel: left
|
||||
- tas2780.update_config:
|
||||
id: tas2780_amp
|
||||
amp_level: !lambda return 12;
|
||||
vol_range_min: !lambda return 0.1f;
|
||||
vol_range_max: !lambda return 0.8f;
|
||||
channel: !lambda return tas2780::RIGHT_CHANNEL;
|
||||
- tas2780.deactivate:
|
||||
id: tas2780_amp
|
||||
- tas2780.reset:
|
||||
|
||||
@@ -30,9 +30,6 @@ binary_sensor:
|
||||
id: kb
|
||||
key: 0x28 # Enter
|
||||
modifiers: !lambda return 0;
|
||||
- tinyusb_keyboard.press:
|
||||
id: kb
|
||||
key: !lambda return 0x04;
|
||||
on_release:
|
||||
- tinyusb_keyboard.release: kb
|
||||
|
||||
@@ -42,8 +39,5 @@ binary_sensor:
|
||||
- tinyusb_keyboard.media_press:
|
||||
id: kb
|
||||
usage: 0xE9 # Volume Up
|
||||
- tinyusb_keyboard.media_press:
|
||||
id: kb
|
||||
usage: !lambda return 0xEA;
|
||||
on_release:
|
||||
- tinyusb_keyboard.media_release: kb
|
||||
@@ -15,15 +15,6 @@ esphome:
|
||||
- tm1651.set_brightness:
|
||||
id: tm1651_battery
|
||||
brightness: 2
|
||||
- tm1651.set_level_percent:
|
||||
id: tm1651_battery
|
||||
level_percent: !lambda return 75;
|
||||
- tm1651.set_level:
|
||||
id: tm1651_battery
|
||||
level: !lambda return 3;
|
||||
- tm1651.set_brightness:
|
||||
id: tm1651_battery
|
||||
brightness: !lambda return 1;
|
||||
- tm1651.turn_on:
|
||||
id: tm1651_battery
|
||||
- tm1651.turn_off:
|
||||
|
||||
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user