mirror of
https://github.com/esphome/esphome.git
synced 2024-11-24 07:58:09 +01:00
Merge remote-tracking branch 'refs/remotes/origin/gsm' into gsm
This commit is contained in:
commit
00aab9ce8d
98 changed files with 887 additions and 609 deletions
2
.github/workflows/ci-docker.yml
vendored
2
.github/workflows/ci-docker.yml
vendored
|
@ -46,7 +46,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
python-version: "3.9"
|
python-version: "3.9"
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.5.0
|
uses: docker/setup-buildx-action@v3.6.1
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3.2.0
|
uses: docker/setup-qemu-action@v3.2.0
|
||||||
|
|
||||||
|
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
@ -90,7 +90,7 @@ jobs:
|
||||||
python-version: "3.9"
|
python-version: "3.9"
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.5.0
|
uses: docker/setup-buildx-action@v3.6.1
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
if: matrix.platform != 'linux/amd64'
|
if: matrix.platform != 'linux/amd64'
|
||||||
uses: docker/setup-qemu-action@v3.2.0
|
uses: docker/setup-qemu-action@v3.2.0
|
||||||
|
@ -184,7 +184,7 @@ jobs:
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.5.0
|
uses: docker/setup-buildx-action@v3.6.1
|
||||||
|
|
||||||
- name: Log in to docker hub
|
- name: Log in to docker hub
|
||||||
if: matrix.registry == 'dockerhub'
|
if: matrix.registry == 'dockerhub'
|
||||||
|
|
|
@ -428,6 +428,7 @@ esphome/components/veml7700/* @latonita
|
||||||
esphome/components/version/* @esphome/core
|
esphome/components/version/* @esphome/core
|
||||||
esphome/components/voice_assistant/* @jesserockz
|
esphome/components/voice_assistant/* @jesserockz
|
||||||
esphome/components/wake_on_lan/* @clydebarrow @willwill2will54
|
esphome/components/wake_on_lan/* @clydebarrow @willwill2will54
|
||||||
|
esphome/components/watchdog/* @oarcher
|
||||||
esphome/components/waveshare_epaper/* @clydebarrow
|
esphome/components/waveshare_epaper/* @clydebarrow
|
||||||
esphome/components/web_server_base/* @OttoWinter
|
esphome/components/web_server_base/* @OttoWinter
|
||||||
esphome/components/web_server_idf/* @dentra
|
esphome/components/web_server_idf/* @dentra
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# PYTHON_ARGCOMPLETE_OK
|
# PYTHON_ARGCOMPLETE_OK
|
||||||
import argparse
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import argcomplete
|
import argcomplete
|
||||||
|
|
||||||
|
@ -39,14 +39,14 @@ from esphome.const import (
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, EsphomeError, coroutine
|
from esphome.core import CORE, EsphomeError, coroutine
|
||||||
from esphome.helpers import indent, is_ip_address
|
from esphome.helpers import indent, is_ip_address
|
||||||
|
from esphome.log import Fore, color, setup_log
|
||||||
from esphome.util import (
|
from esphome.util import (
|
||||||
|
get_serial_ports,
|
||||||
|
list_yaml_files,
|
||||||
run_external_command,
|
run_external_command,
|
||||||
run_external_process,
|
run_external_process,
|
||||||
safe_print,
|
safe_print,
|
||||||
list_yaml_files,
|
|
||||||
get_serial_ports,
|
|
||||||
)
|
)
|
||||||
from esphome.log import color, setup_log, Fore
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ def get_port_type(port):
|
||||||
|
|
||||||
def run_miniterm(config, port):
|
def run_miniterm(config, port):
|
||||||
import serial
|
import serial
|
||||||
|
|
||||||
from esphome import platformio_api
|
from esphome import platformio_api
|
||||||
|
|
||||||
if CONF_LOGGER not in config:
|
if CONF_LOGGER not in config:
|
||||||
|
@ -596,9 +597,10 @@ def command_update_all(args):
|
||||||
|
|
||||||
|
|
||||||
def command_idedata(args, config):
|
def command_idedata(args, config):
|
||||||
from esphome import platformio_api
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from esphome import platformio_api
|
||||||
|
|
||||||
logging.disable(logging.INFO)
|
logging.disable(logging.INFO)
|
||||||
logging.disable(logging.WARNING)
|
logging.disable(logging.WARNING)
|
||||||
|
|
||||||
|
@ -747,7 +749,14 @@ def parse_args(argv):
|
||||||
)
|
)
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=f"ESPHome v{const.__version__}", parents=[options_parser]
|
description=f"ESPHome {const.__version__}", parents=[options_parser]
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--version",
|
||||||
|
action="version",
|
||||||
|
version=f"Version: {const.__version__}",
|
||||||
|
help="Print the ESPHome version and exit.",
|
||||||
)
|
)
|
||||||
|
|
||||||
mqtt_options = argparse.ArgumentParser(add_help=False)
|
mqtt_options = argparse.ArgumentParser(add_help=False)
|
||||||
|
@ -948,67 +957,6 @@ def parse_args(argv):
|
||||||
# a deprecation warning).
|
# a deprecation warning).
|
||||||
arguments = argv[1:]
|
arguments = argv[1:]
|
||||||
|
|
||||||
# On Python 3.9+ we can simply set exit_on_error=False in the constructor
|
|
||||||
def _raise(x):
|
|
||||||
raise argparse.ArgumentError(None, x)
|
|
||||||
|
|
||||||
# First, try new-style parsing, but don't exit in case of failure
|
|
||||||
try:
|
|
||||||
# duplicate parser so that we can use the original one to raise errors later on
|
|
||||||
current_parser = argparse.ArgumentParser(add_help=False, parents=[parser])
|
|
||||||
current_parser.set_defaults(deprecated_argv_suggestion=None)
|
|
||||||
current_parser.error = _raise
|
|
||||||
return current_parser.parse_args(arguments)
|
|
||||||
except argparse.ArgumentError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Second, try compat parsing and rearrange the command-line if it succeeds
|
|
||||||
# Disable argparse's built-in help option and add it manually to prevent this
|
|
||||||
# parser from printing the help messagefor the old format when invoked with -h.
|
|
||||||
compat_parser = argparse.ArgumentParser(parents=[options_parser], add_help=False)
|
|
||||||
compat_parser.add_argument("-h", "--help", action="store_true")
|
|
||||||
compat_parser.add_argument("configuration", nargs="*")
|
|
||||||
compat_parser.add_argument(
|
|
||||||
"command",
|
|
||||||
choices=[
|
|
||||||
"config",
|
|
||||||
"compile",
|
|
||||||
"upload",
|
|
||||||
"logs",
|
|
||||||
"run",
|
|
||||||
"clean-mqtt",
|
|
||||||
"wizard",
|
|
||||||
"mqtt-fingerprint",
|
|
||||||
"version",
|
|
||||||
"clean",
|
|
||||||
"dashboard",
|
|
||||||
"vscode",
|
|
||||||
"update-all",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
compat_parser.error = _raise
|
|
||||||
result, unparsed = compat_parser.parse_known_args(argv[1:])
|
|
||||||
last_option = len(arguments) - len(unparsed) - 1 - len(result.configuration)
|
|
||||||
unparsed = [
|
|
||||||
"--device" if arg in ("--upload-port", "--serial-port") else arg
|
|
||||||
for arg in unparsed
|
|
||||||
]
|
|
||||||
arguments = (
|
|
||||||
arguments[0:last_option]
|
|
||||||
+ [result.command]
|
|
||||||
+ result.configuration
|
|
||||||
+ unparsed
|
|
||||||
)
|
|
||||||
deprecated_argv_suggestion = arguments
|
|
||||||
except argparse.ArgumentError:
|
|
||||||
# old-style parsing failed, don't suggest any argument
|
|
||||||
deprecated_argv_suggestion = None
|
|
||||||
|
|
||||||
# Finally, run the new-style parser again with the possibly swapped arguments,
|
|
||||||
# and let it error out if the command is unparsable.
|
|
||||||
parser.set_defaults(deprecated_argv_suggestion=deprecated_argv_suggestion)
|
|
||||||
argcomplete.autocomplete(parser)
|
argcomplete.autocomplete(parser)
|
||||||
return parser.parse_args(arguments)
|
return parser.parse_args(arguments)
|
||||||
|
|
||||||
|
@ -1023,13 +971,6 @@ def run_esphome(argv):
|
||||||
# Show timestamp for dashboard access logs
|
# Show timestamp for dashboard access logs
|
||||||
args.command == "dashboard",
|
args.command == "dashboard",
|
||||||
)
|
)
|
||||||
if args.deprecated_argv_suggestion is not None and args.command != "vscode":
|
|
||||||
_LOGGER.warning(
|
|
||||||
"Calling ESPHome with the configuration before the command is deprecated "
|
|
||||||
"and will be removed in the future. "
|
|
||||||
)
|
|
||||||
_LOGGER.warning("Please instead use:")
|
|
||||||
_LOGGER.warning(" esphome %s", " ".join(args.deprecated_argv_suggestion))
|
|
||||||
|
|
||||||
if sys.version_info < (3, 8, 0):
|
if sys.version_info < (3, 8, 0):
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
|
|
|
@ -7,10 +7,10 @@ from esphome.const import (
|
||||||
CONF_ELSE,
|
CONF_ELSE,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_THEN,
|
CONF_THEN,
|
||||||
|
CONF_TIME,
|
||||||
CONF_TIMEOUT,
|
CONF_TIMEOUT,
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
CONF_TYPE_ID,
|
CONF_TYPE_ID,
|
||||||
CONF_TIME,
|
|
||||||
CONF_UPDATE_INTERVAL,
|
CONF_UPDATE_INTERVAL,
|
||||||
)
|
)
|
||||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||||
|
|
|
@ -8,55 +8,78 @@
|
||||||
# want to break suddenly due to a rename (this file will get backports for features).
|
# want to break suddenly due to a rename (this file will get backports for features).
|
||||||
|
|
||||||
# pylint: disable=unused-import
|
# pylint: disable=unused-import
|
||||||
from esphome.cpp_generator import ( # noqa
|
from esphome.cpp_generator import ( # noqa: F401
|
||||||
|
ArrayInitializer,
|
||||||
Expression,
|
Expression,
|
||||||
|
LineComment,
|
||||||
|
MockObj,
|
||||||
|
MockObjClass,
|
||||||
|
Pvariable,
|
||||||
RawExpression,
|
RawExpression,
|
||||||
RawStatement,
|
RawStatement,
|
||||||
TemplateArguments,
|
|
||||||
StructInitializer,
|
|
||||||
ArrayInitializer,
|
|
||||||
safe_exp,
|
|
||||||
Statement,
|
Statement,
|
||||||
LineComment,
|
StructInitializer,
|
||||||
progmem_array,
|
TemplateArguments,
|
||||||
static_const_array,
|
|
||||||
statement,
|
|
||||||
variable,
|
|
||||||
with_local_variable,
|
|
||||||
new_variable,
|
|
||||||
Pvariable,
|
|
||||||
new_Pvariable,
|
|
||||||
add,
|
add,
|
||||||
add_global,
|
|
||||||
add_library,
|
|
||||||
add_build_flag,
|
add_build_flag,
|
||||||
add_define,
|
add_define,
|
||||||
|
add_global,
|
||||||
|
add_library,
|
||||||
add_platformio_option,
|
add_platformio_option,
|
||||||
get_variable,
|
get_variable,
|
||||||
get_variable_with_full_id,
|
get_variable_with_full_id,
|
||||||
process_lambda,
|
|
||||||
is_template,
|
is_template,
|
||||||
|
new_Pvariable,
|
||||||
|
new_variable,
|
||||||
|
process_lambda,
|
||||||
|
progmem_array,
|
||||||
|
safe_exp,
|
||||||
|
statement,
|
||||||
|
static_const_array,
|
||||||
templatable,
|
templatable,
|
||||||
MockObj,
|
variable,
|
||||||
MockObjClass,
|
with_local_variable,
|
||||||
)
|
)
|
||||||
from esphome.cpp_helpers import ( # noqa
|
from esphome.cpp_helpers import ( # noqa: F401
|
||||||
gpio_pin_expression,
|
|
||||||
register_component,
|
|
||||||
build_registry_entry,
|
build_registry_entry,
|
||||||
build_registry_list,
|
build_registry_list,
|
||||||
extract_registry_entry_config,
|
extract_registry_entry_config,
|
||||||
register_parented,
|
gpio_pin_expression,
|
||||||
past_safe_mode,
|
past_safe_mode,
|
||||||
|
register_component,
|
||||||
|
register_parented,
|
||||||
)
|
)
|
||||||
from esphome.cpp_types import ( # noqa
|
from esphome.cpp_types import ( # noqa: F401
|
||||||
global_ns,
|
NAN,
|
||||||
void,
|
App,
|
||||||
nullptr,
|
Application,
|
||||||
float_,
|
Component,
|
||||||
double,
|
ComponentPtr,
|
||||||
|
Controller,
|
||||||
|
EntityBase,
|
||||||
|
EntityCategory,
|
||||||
|
ESPTime,
|
||||||
|
GPIOPin,
|
||||||
|
InternalGPIOPin,
|
||||||
|
JsonObject,
|
||||||
|
JsonObjectConst,
|
||||||
|
Parented,
|
||||||
|
PollingComponent,
|
||||||
|
arduino_json_ns,
|
||||||
bool_,
|
bool_,
|
||||||
|
const_char_ptr,
|
||||||
|
double,
|
||||||
|
esphome_ns,
|
||||||
|
float_,
|
||||||
|
global_ns,
|
||||||
|
gpio_Flags,
|
||||||
|
int16,
|
||||||
|
int32,
|
||||||
|
int64,
|
||||||
int_,
|
int_,
|
||||||
|
nullptr,
|
||||||
|
optional,
|
||||||
|
size_t,
|
||||||
std_ns,
|
std_ns,
|
||||||
std_shared_ptr,
|
std_shared_ptr,
|
||||||
std_string,
|
std_string,
|
||||||
|
@ -66,28 +89,5 @@ from esphome.cpp_types import ( # noqa
|
||||||
uint16,
|
uint16,
|
||||||
uint32,
|
uint32,
|
||||||
uint64,
|
uint64,
|
||||||
int16,
|
void,
|
||||||
int32,
|
|
||||||
int64,
|
|
||||||
size_t,
|
|
||||||
const_char_ptr,
|
|
||||||
NAN,
|
|
||||||
esphome_ns,
|
|
||||||
App,
|
|
||||||
EntityBase,
|
|
||||||
Component,
|
|
||||||
ComponentPtr,
|
|
||||||
PollingComponent,
|
|
||||||
Application,
|
|
||||||
optional,
|
|
||||||
arduino_json_ns,
|
|
||||||
JsonObject,
|
|
||||||
JsonObjectConst,
|
|
||||||
Controller,
|
|
||||||
GPIOPin,
|
|
||||||
InternalGPIOPin,
|
|
||||||
gpio_Flags,
|
|
||||||
EntityCategory,
|
|
||||||
Parented,
|
|
||||||
ESPTime,
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import esphome.codegen as cg
|
from esphome import automation
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.automation import maybe_simple_id
|
from esphome.automation import maybe_simple_id
|
||||||
from esphome.components import esp32_ble_tracker, esp32_ble_client
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import esp32_ble_client, esp32_ble_tracker
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_CHARACTERISTIC_UUID,
|
CONF_CHARACTERISTIC_UUID,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
@ -13,7 +14,6 @@ from esphome.const import (
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
CONF_VALUE,
|
CONF_VALUE,
|
||||||
)
|
)
|
||||||
from esphome import automation
|
|
||||||
|
|
||||||
AUTO_LOAD = ["esp32_ble_client"]
|
AUTO_LOAD = ["esp32_ble_client"]
|
||||||
CODEOWNERS = ["@buxtronix", "@clydebarrow"]
|
CODEOWNERS = ["@buxtronix", "@clydebarrow"]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components import ble_client, esp32_ble_tracker, output
|
from esphome.components import ble_client, esp32_ble_tracker, output
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_CHARACTERISTIC_UUID, CONF_ID, CONF_SERVICE_UUID
|
from esphome.const import CONF_CHARACTERISTIC_UUID, CONF_ID, CONF_SERVICE_UUID
|
||||||
|
|
||||||
from .. import ble_client_ns
|
from .. import ble_client_ns
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
|
from esphome import automation
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import ble_client, esp32_ble_tracker, sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import sensor, ble_client, esp32_ble_tracker
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_CHARACTERISTIC_UUID,
|
CONF_CHARACTERISTIC_UUID,
|
||||||
CONF_LAMBDA,
|
CONF_LAMBDA,
|
||||||
|
CONF_SERVICE_UUID,
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
CONF_SERVICE_UUID,
|
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
STATE_CLASS_MEASUREMENT,
|
STATE_CLASS_MEASUREMENT,
|
||||||
UNIT_DECIBEL_MILLIWATT,
|
UNIT_DECIBEL_MILLIWATT,
|
||||||
)
|
)
|
||||||
from esphome import automation
|
|
||||||
from .. import ble_client_ns
|
from .. import ble_client_ns
|
||||||
|
|
||||||
DEPENDENCIES = ["ble_client"]
|
DEPENDENCIES = ["ble_client"]
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import ble_client, switch
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import switch, ble_client
|
|
||||||
from esphome.const import ICON_BLUETOOTH
|
from esphome.const import ICON_BLUETOOTH
|
||||||
|
|
||||||
from .. import ble_client_ns
|
from .. import ble_client_ns
|
||||||
|
|
||||||
BLEClientSwitch = ble_client_ns.class_(
|
BLEClientSwitch = ble_client_ns.class_(
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
|
from esphome import automation
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import ble_client, esp32_ble_tracker, text_sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import text_sensor, ble_client, esp32_ble_tracker
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_CHARACTERISTIC_UUID,
|
CONF_CHARACTERISTIC_UUID,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_TRIGGER_ID,
|
|
||||||
CONF_SERVICE_UUID,
|
CONF_SERVICE_UUID,
|
||||||
|
CONF_TRIGGER_ID,
|
||||||
)
|
)
|
||||||
from esphome import automation
|
|
||||||
from .. import ble_client_ns
|
from .. import ble_client_ns
|
||||||
|
|
||||||
DEPENDENCIES = ["ble_client"]
|
DEPENDENCIES = ["ble_client"]
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components import binary_sensor, esp32_ble_tracker
|
from esphome.components import binary_sensor, esp32_ble_tracker
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_MAC_ADDRESS,
|
|
||||||
CONF_SERVICE_UUID,
|
|
||||||
CONF_IBEACON_MAJOR,
|
CONF_IBEACON_MAJOR,
|
||||||
CONF_IBEACON_MINOR,
|
CONF_IBEACON_MINOR,
|
||||||
CONF_IBEACON_UUID,
|
CONF_IBEACON_UUID,
|
||||||
|
CONF_MAC_ADDRESS,
|
||||||
CONF_MIN_RSSI,
|
CONF_MIN_RSSI,
|
||||||
|
CONF_SERVICE_UUID,
|
||||||
CONF_TIMEOUT,
|
CONF_TIMEOUT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import esp32_ble_tracker, sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import sensor, esp32_ble_tracker
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_IBEACON_MAJOR,
|
CONF_IBEACON_MAJOR,
|
||||||
CONF_IBEACON_MINOR,
|
CONF_IBEACON_MINOR,
|
||||||
CONF_IBEACON_UUID,
|
CONF_IBEACON_UUID,
|
||||||
CONF_SERVICE_UUID,
|
|
||||||
CONF_MAC_ADDRESS,
|
CONF_MAC_ADDRESS,
|
||||||
|
CONF_SERVICE_UUID,
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
STATE_CLASS_MEASUREMENT,
|
STATE_CLASS_MEASUREMENT,
|
||||||
UNIT_DECIBEL_MILLIWATT,
|
UNIT_DECIBEL_MILLIWATT,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import esp32_ble_tracker, text_sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import text_sensor, esp32_ble_tracker
|
|
||||||
|
|
||||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from esphome.components import esp32_ble_tracker, esp32_ble_client
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.const import CONF_ACTIVE, CONF_ID
|
from esphome.components import esp32_ble_client, esp32_ble_tracker
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_ACTIVE, CONF_ID
|
||||||
|
|
||||||
AUTO_LOAD = ["esp32_ble_client", "esp32_ble_tracker"]
|
AUTO_LOAD = ["esp32_ble_client", "esp32_ble_tracker"]
|
||||||
DEPENDENCIES = ["api", "esp32"]
|
DEPENDENCIES = ["api", "esp32"]
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Union, Optional
|
|
||||||
from pathlib import Path
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import esphome.final_validate as fv
|
from pathlib import Path
|
||||||
|
from typing import Optional, Union
|
||||||
|
|
||||||
from esphome.helpers import copy_file_if_changed, write_file_if_changed, mkdir_p
|
from esphome import git
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ADVANCED,
|
CONF_ADVANCED,
|
||||||
CONF_BOARD,
|
CONF_BOARD,
|
||||||
|
@ -15,6 +16,7 @@ from esphome.const import (
|
||||||
CONF_IGNORE_EFUSE_MAC_CRC,
|
CONF_IGNORE_EFUSE_MAC_CRC,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_PATH,
|
CONF_PATH,
|
||||||
|
CONF_PLATFORM_VERSION,
|
||||||
CONF_PLATFORMIO_OPTIONS,
|
CONF_PLATFORMIO_OPTIONS,
|
||||||
CONF_REF,
|
CONF_REF,
|
||||||
CONF_REFRESH,
|
CONF_REFRESH,
|
||||||
|
@ -32,13 +34,12 @@ from esphome.const import (
|
||||||
TYPE_GIT,
|
TYPE_GIT,
|
||||||
TYPE_LOCAL,
|
TYPE_LOCAL,
|
||||||
__version__,
|
__version__,
|
||||||
CONF_PLATFORM_VERSION,
|
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, HexInt, TimePeriod
|
from esphome.core import CORE, HexInt, TimePeriod
|
||||||
import esphome.config_validation as cv
|
import esphome.final_validate as fv
|
||||||
import esphome.codegen as cg
|
from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
|
||||||
from esphome import git
|
|
||||||
|
|
||||||
|
from .boards import BOARDS
|
||||||
from .const import ( # noqa
|
from .const import ( # noqa
|
||||||
KEY_BOARD,
|
KEY_BOARD,
|
||||||
KEY_COMPONENTS,
|
KEY_COMPONENTS,
|
||||||
|
@ -54,12 +55,10 @@ from .const import ( # noqa
|
||||||
VARIANT_FRIENDLY,
|
VARIANT_FRIENDLY,
|
||||||
VARIANTS,
|
VARIANTS,
|
||||||
)
|
)
|
||||||
from .boards import BOARDS
|
|
||||||
|
|
||||||
# force import gpio to register pin schema
|
# force import gpio to register pin schema
|
||||||
from .gpio import esp32_pin_to_code # noqa
|
from .gpio import esp32_pin_to_code # noqa
|
||||||
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
CODEOWNERS = ["@esphome/core"]
|
CODEOWNERS = ["@esphome/core"]
|
||||||
AUTO_LOAD = ["preferences"]
|
AUTO_LOAD = ["preferences"]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .const import VARIANT_ESP32, VARIANT_ESP32S2, VARIANT_ESP32C3, VARIANT_ESP32S3
|
from .const import VARIANT_ESP32, VARIANT_ESP32C3, VARIANT_ESP32S2, VARIANT_ESP32S3
|
||||||
|
|
||||||
ESP32_BASE_PINS = {
|
ESP32_BASE_PINS = {
|
||||||
"TX": 1,
|
"TX": 1,
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from esphome import pins
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
CONF_IGNORE_PIN_VALIDATION_ERROR,
|
||||||
|
CONF_IGNORE_STRAPPING_WARNING,
|
||||||
CONF_INVERTED,
|
CONF_INVERTED,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
CONF_NUMBER,
|
CONF_NUMBER,
|
||||||
CONF_OPEN_DRAIN,
|
CONF_OPEN_DRAIN,
|
||||||
CONF_OUTPUT,
|
CONF_OUTPUT,
|
||||||
CONF_IGNORE_PIN_VALIDATION_ERROR,
|
|
||||||
CONF_IGNORE_STRAPPING_WARNING,
|
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
)
|
)
|
||||||
from esphome import pins
|
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.codegen as cg
|
|
||||||
|
|
||||||
from . import boards
|
from . import boards
|
||||||
from .const import (
|
from .const import (
|
||||||
|
@ -24,22 +24,21 @@ from .const import (
|
||||||
KEY_ESP32,
|
KEY_ESP32,
|
||||||
KEY_VARIANT,
|
KEY_VARIANT,
|
||||||
VARIANT_ESP32,
|
VARIANT_ESP32,
|
||||||
VARIANT_ESP32C3,
|
|
||||||
VARIANT_ESP32S2,
|
|
||||||
VARIANT_ESP32S3,
|
|
||||||
VARIANT_ESP32C2,
|
VARIANT_ESP32C2,
|
||||||
|
VARIANT_ESP32C3,
|
||||||
VARIANT_ESP32C6,
|
VARIANT_ESP32C6,
|
||||||
VARIANT_ESP32H2,
|
VARIANT_ESP32H2,
|
||||||
|
VARIANT_ESP32S2,
|
||||||
|
VARIANT_ESP32S3,
|
||||||
esp32_ns,
|
esp32_ns,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .gpio_esp32 import esp32_validate_gpio_pin, esp32_validate_supports
|
from .gpio_esp32 import esp32_validate_gpio_pin, esp32_validate_supports
|
||||||
from .gpio_esp32_s2 import esp32_s2_validate_gpio_pin, esp32_s2_validate_supports
|
|
||||||
from .gpio_esp32_c3 import esp32_c3_validate_gpio_pin, esp32_c3_validate_supports
|
|
||||||
from .gpio_esp32_s3 import esp32_s3_validate_gpio_pin, esp32_s3_validate_supports
|
|
||||||
from .gpio_esp32_c2 import esp32_c2_validate_gpio_pin, esp32_c2_validate_supports
|
from .gpio_esp32_c2 import esp32_c2_validate_gpio_pin, esp32_c2_validate_supports
|
||||||
|
from .gpio_esp32_c3 import esp32_c3_validate_gpio_pin, esp32_c3_validate_supports
|
||||||
from .gpio_esp32_c6 import esp32_c6_validate_gpio_pin, esp32_c6_validate_supports
|
from .gpio_esp32_c6 import esp32_c6_validate_gpio_pin, esp32_c6_validate_supports
|
||||||
from .gpio_esp32_h2 import esp32_h2_validate_gpio_pin, esp32_h2_validate_supports
|
from .gpio_esp32_h2 import esp32_h2_validate_gpio_pin, esp32_h2_validate_supports
|
||||||
|
from .gpio_esp32_s2 import esp32_s2_validate_gpio_pin, esp32_s2_validate_supports
|
||||||
|
from .gpio_esp32_s3 import esp32_s3_validate_gpio_pin, esp32_s3_validate_supports
|
||||||
|
|
||||||
ESP32InternalGPIOPin = esp32_ns.class_("ESP32InternalGPIOPin", cg.InternalGPIOPin)
|
ESP32InternalGPIOPin = esp32_ns.class_("ESP32InternalGPIOPin", cg.InternalGPIOPin)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_INPUT,
|
CONF_INPUT,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
|
@ -8,10 +9,8 @@ from esphome.const import (
|
||||||
CONF_PULLDOWN,
|
CONF_PULLDOWN,
|
||||||
CONF_PULLUP,
|
CONF_PULLUP,
|
||||||
)
|
)
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.pins import check_strapping_pin
|
from esphome.pins import check_strapping_pin
|
||||||
|
|
||||||
|
|
||||||
_ESP_SDIO_PINS = {
|
_ESP_SDIO_PINS = {
|
||||||
6: "Flash Clock",
|
6: "Flash Clock",
|
||||||
7: "Flash Data 0",
|
7: "Flash Data 0",
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||||
from esphome.pins import check_strapping_pin
|
from esphome.pins import check_strapping_pin
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
|
|
||||||
_ESP32C2_STRAPPING_PINS = {8, 9}
|
_ESP32C2_STRAPPING_PINS = {8, 9}
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from esphome.const import (
|
|
||||||
CONF_INPUT,
|
|
||||||
CONF_MODE,
|
|
||||||
CONF_NUMBER,
|
|
||||||
)
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||||
from esphome.pins import check_strapping_pin
|
from esphome.pins import check_strapping_pin
|
||||||
|
|
||||||
_ESP32C3_SPI_PSRAM_PINS = {
|
_ESP32C3_SPI_PSRAM_PINS = {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||||
from esphome.pins import check_strapping_pin
|
from esphome.pins import check_strapping_pin
|
||||||
|
|
||||||
_ESP32C6_SPI_PSRAM_PINS = {
|
_ESP32C6_SPI_PSRAM_PINS = {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||||
|
|
||||||
_ESP32H2_SPI_FLASH_PINS = {6, 7, 15, 16, 17, 18, 19, 20, 21}
|
_ESP32H2_SPI_FLASH_PINS = {6, 7, 15, 16, 17, 18, 19, 20, 21}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_INPUT,
|
CONF_INPUT,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
|
@ -8,8 +9,6 @@ from esphome.const import (
|
||||||
CONF_PULLDOWN,
|
CONF_PULLDOWN,
|
||||||
CONF_PULLUP,
|
CONF_PULLUP,
|
||||||
)
|
)
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.pins import check_strapping_pin
|
from esphome.pins import check_strapping_pin
|
||||||
|
|
||||||
_ESP32S2_SPI_PSRAM_PINS = {
|
_ESP32S2_SPI_PSRAM_PINS = {
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from esphome.const import (
|
|
||||||
CONF_INPUT,
|
|
||||||
CONF_MODE,
|
|
||||||
CONF_NUMBER,
|
|
||||||
)
|
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||||
from esphome.pins import check_strapping_pin
|
from esphome.pins import check_strapping_pin
|
||||||
|
|
||||||
_ESP_32S3_SPI_PSRAM_PINS = {
|
_ESP_32S3_SPI_PSRAM_PINS = {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components.esp32 import add_idf_sdkconfig_option, const, get_esp32_variant
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ENABLE_ON_BOOT, CONF_ID
|
from esphome.const import CONF_ENABLE_ON_BOOT, CONF_ID
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant, const
|
|
||||||
|
|
||||||
DEPENDENCIES = ["esp32"]
|
DEPENDENCIES = ["esp32"]
|
||||||
CODEOWNERS = ["@jesserockz", "@Rapsssito"]
|
CODEOWNERS = ["@jesserockz", "@Rapsssito"]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components.esp32_ble import CONF_BLE_ID
|
|
||||||
from esphome.const import CONF_ID, CONF_TYPE, CONF_UUID, CONF_TX_POWER
|
|
||||||
from esphome.core import CORE, TimePeriod
|
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
|
||||||
from esphome.components import esp32_ble
|
from esphome.components import esp32_ble
|
||||||
|
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||||
|
from esphome.components.esp32_ble import CONF_BLE_ID
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_ID, CONF_TX_POWER, CONF_TYPE, CONF_UUID
|
||||||
|
from esphome.core import CORE, TimePeriod
|
||||||
|
|
||||||
AUTO_LOAD = ["esp32_ble"]
|
AUTO_LOAD = ["esp32_ble"]
|
||||||
DEPENDENCIES = ["esp32"]
|
DEPENDENCIES = ["esp32"]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
from esphome.components import esp32_ble_tracker
|
from esphome.components import esp32_ble_tracker
|
||||||
|
|
||||||
AUTO_LOAD = ["esp32_ble_tracker"]
|
AUTO_LOAD = ["esp32_ble_tracker"]
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import esp32_ble
|
||||||
|
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ID, CONF_MODEL
|
from esphome.const import CONF_ID, CONF_MODEL
|
||||||
from esphome.components import esp32_ble
|
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
|
||||||
|
|
||||||
AUTO_LOAD = ["esp32_ble"]
|
AUTO_LOAD = ["esp32_ble"]
|
||||||
CODEOWNERS = ["@jesserockz", "@clydebarrow", "@Rapsssito"]
|
CODEOWNERS = ["@jesserockz", "@clydebarrow", "@Rapsssito"]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
|
import esphome.codegen as cg
|
||||||
from esphome.components import esp32_ble
|
from esphome.components import esp32_ble
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ACTIVE,
|
CONF_ACTIVE,
|
||||||
CONF_DURATION,
|
CONF_DURATION,
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.final_validate as fv
|
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant
|
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant
|
||||||
from esphome.components.esp32.const import (
|
from esphome.components.esp32.const import (
|
||||||
|
@ -8,31 +6,33 @@ from esphome.components.esp32.const import (
|
||||||
VARIANT_ESP32S2,
|
VARIANT_ESP32S2,
|
||||||
VARIANT_ESP32S3,
|
VARIANT_ESP32S3,
|
||||||
)
|
)
|
||||||
|
from esphome.components.network import IPAddress
|
||||||
|
from esphome.components.spi import CONF_INTERFACE_INDEX, get_spi_interface
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_DOMAIN,
|
CONF_ADDRESS,
|
||||||
CONF_ID,
|
CONF_CLK_PIN,
|
||||||
CONF_VALUE,
|
CONF_CS_PIN,
|
||||||
CONF_MANUAL_IP,
|
|
||||||
CONF_STATIC_IP,
|
|
||||||
CONF_TYPE,
|
|
||||||
CONF_USE_ADDRESS,
|
|
||||||
CONF_GATEWAY,
|
|
||||||
CONF_SUBNET,
|
|
||||||
CONF_DNS1,
|
CONF_DNS1,
|
||||||
CONF_DNS2,
|
CONF_DNS2,
|
||||||
CONF_CLK_PIN,
|
CONF_DOMAIN,
|
||||||
|
CONF_GATEWAY,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_INTERRUPT_PIN,
|
||||||
|
CONF_MANUAL_IP,
|
||||||
CONF_MISO_PIN,
|
CONF_MISO_PIN,
|
||||||
CONF_MOSI_PIN,
|
CONF_MOSI_PIN,
|
||||||
CONF_CS_PIN,
|
CONF_PAGE_ID,
|
||||||
CONF_INTERRUPT_PIN,
|
|
||||||
CONF_RESET_PIN,
|
CONF_RESET_PIN,
|
||||||
CONF_SPI,
|
CONF_SPI,
|
||||||
CONF_PAGE_ID,
|
CONF_STATIC_IP,
|
||||||
CONF_ADDRESS,
|
CONF_SUBNET,
|
||||||
|
CONF_TYPE,
|
||||||
|
CONF_USE_ADDRESS,
|
||||||
|
CONF_VALUE,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
from esphome.components.network import IPAddress
|
import esphome.final_validate as fv
|
||||||
from esphome.components.spi import get_spi_interface, CONF_INTERFACE_INDEX
|
|
||||||
|
|
||||||
CONFLICTS_WITH = ["wifi"]
|
CONFLICTS_WITH = ["wifi"]
|
||||||
DEPENDENCIES = ["esp32"]
|
DEPENDENCIES = ["esp32"]
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components import text_sensor
|
from esphome.components import text_sensor
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_IP_ADDRESS,
|
|
||||||
CONF_DNS_ADDRESS,
|
CONF_DNS_ADDRESS,
|
||||||
|
CONF_IP_ADDRESS,
|
||||||
CONF_MAC_ADDRESS,
|
CONF_MAC_ADDRESS,
|
||||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,7 @@ from esphome.const import (
|
||||||
from esphome.core import CORE, Lambda
|
from esphome.core import CORE, Lambda
|
||||||
|
|
||||||
DEPENDENCIES = ["network"]
|
DEPENDENCIES = ["network"]
|
||||||
AUTO_LOAD = ["json"]
|
AUTO_LOAD = ["json", "watchdog"]
|
||||||
|
|
||||||
http_request_ns = cg.esphome_ns.namespace("http_request")
|
http_request_ns = cg.esphome_ns.namespace("http_request")
|
||||||
HttpRequestComponent = http_request_ns.class_("HttpRequestComponent", cg.Component)
|
HttpRequestComponent = http_request_ns.class_("HttpRequestComponent", cg.Component)
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/components/network/util.h"
|
#include "esphome/components/network/util.h"
|
||||||
|
#include "esphome/components/watchdog/watchdog.h"
|
||||||
|
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/defines.h"
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#include "watchdog.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace http_request {
|
namespace http_request {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#ifdef USE_ESP_IDF
|
#ifdef USE_ESP_IDF
|
||||||
|
|
||||||
#include "esphome/components/network/util.h"
|
#include "esphome/components/network/util.h"
|
||||||
|
#include "esphome/components/watchdog/watchdog.h"
|
||||||
|
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/defines.h"
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
@ -11,8 +13,6 @@
|
||||||
#include "esp_crt_bundle.h"
|
#include "esp_crt_bundle.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "watchdog.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace http_request {
|
namespace http_request {
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "ota_http_request.h"
|
#include "ota_http_request.h"
|
||||||
#include "../watchdog.h"
|
|
||||||
|
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/defines.h"
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#include "esphome/components/md5/md5.h"
|
#include "esphome/components/md5/md5.h"
|
||||||
|
#include "esphome/components/watchdog/watchdog.h"
|
||||||
#include "esphome/components/ota/ota_backend.h"
|
#include "esphome/components/ota/ota_backend.h"
|
||||||
#include "esphome/components/ota/ota_backend_arduino_esp32.h"
|
#include "esphome/components/ota/ota_backend_arduino_esp32.h"
|
||||||
#include "esphome/components/ota/ota_backend_arduino_esp8266.h"
|
#include "esphome/components/ota/ota_backend_arduino_esp8266.h"
|
||||||
|
|
|
@ -16,13 +16,20 @@ from esphome.final_validate import full_config
|
||||||
from esphome.helpers import write_file_if_changed
|
from esphome.helpers import write_file_if_changed
|
||||||
|
|
||||||
from . import defines as df, helpers, lv_validation as lvalid
|
from . import defines as df, helpers, lv_validation as lvalid
|
||||||
|
from .btn import btn_spec
|
||||||
from .label import label_spec
|
from .label import label_spec
|
||||||
from .lvcode import ConstantLiteral, LvContext
|
from .lvcode import ConstantLiteral, LvContext
|
||||||
|
|
||||||
# from .menu import menu_spec
|
|
||||||
from .obj import obj_spec
|
from .obj import obj_spec
|
||||||
from .schemas import WIDGET_TYPES, any_widget_schema, obj_schema
|
from .schemas import any_widget_schema, obj_schema
|
||||||
from .types import FontEngine, LvglComponent, lv_disp_t_ptr, lv_font_t, lvgl_ns
|
from .touchscreens import touchscreen_schema, touchscreens_to_code
|
||||||
|
from .types import (
|
||||||
|
WIDGET_TYPES,
|
||||||
|
FontEngine,
|
||||||
|
LvglComponent,
|
||||||
|
lv_disp_t_ptr,
|
||||||
|
lv_font_t,
|
||||||
|
lvgl_ns,
|
||||||
|
)
|
||||||
from .widget import LvScrActType, Widget, add_widgets, set_obj_properties
|
from .widget import LvScrActType, Widget, add_widgets, set_obj_properties
|
||||||
|
|
||||||
DOMAIN = "lvgl"
|
DOMAIN = "lvgl"
|
||||||
|
@ -31,11 +38,8 @@ AUTO_LOAD = ("key_provider",)
|
||||||
CODEOWNERS = ("@clydebarrow",)
|
CODEOWNERS = ("@clydebarrow",)
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
for widg in (
|
for w_type in (label_spec, obj_spec, btn_spec):
|
||||||
label_spec,
|
WIDGET_TYPES[w_type.name] = w_type
|
||||||
obj_spec,
|
|
||||||
):
|
|
||||||
WIDGET_TYPES[widg.name] = widg
|
|
||||||
|
|
||||||
lv_scr_act_spec = LvScrActType()
|
lv_scr_act_spec = LvScrActType()
|
||||||
lv_scr_act = Widget.create(
|
lv_scr_act = Widget.create(
|
||||||
|
@ -93,7 +97,7 @@ def final_validation(config):
|
||||||
"Using auto_clear_enabled: true in display config not compatible with LVGL"
|
"Using auto_clear_enabled: true in display config not compatible with LVGL"
|
||||||
)
|
)
|
||||||
buffer_frac = config[CONF_BUFFER_SIZE]
|
buffer_frac = config[CONF_BUFFER_SIZE]
|
||||||
if not CORE.is_host and buffer_frac > 0.5 and "psram" not in global_config:
|
if CORE.is_esp32 and buffer_frac > 0.5 and "psram" not in global_config:
|
||||||
LOGGER.warning("buffer_size: may need to be reduced without PSRAM")
|
LOGGER.warning("buffer_size: may need to be reduced without PSRAM")
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +136,7 @@ async def to_code(config):
|
||||||
cg.add_global(lvgl_ns.using)
|
cg.add_global(lvgl_ns.using)
|
||||||
lv_component = cg.new_Pvariable(config[CONF_ID])
|
lv_component = cg.new_Pvariable(config[CONF_ID])
|
||||||
await cg.register_component(lv_component, config)
|
await cg.register_component(lv_component, config)
|
||||||
Widget.create(config[CONF_ID], lv_component, WIDGET_TYPES[df.CONF_OBJ], config)
|
Widget.create(config[CONF_ID], lv_component, obj_spec, config)
|
||||||
for display in config[df.CONF_DISPLAYS]:
|
for display in config[df.CONF_DISPLAYS]:
|
||||||
cg.add(lv_component.add_display(await cg.get_variable(display)))
|
cg.add(lv_component.add_display(await cg.get_variable(display)))
|
||||||
|
|
||||||
|
@ -152,7 +156,7 @@ async def to_code(config):
|
||||||
await cg.get_variable(font)
|
await cg.get_variable(font)
|
||||||
cg.new_Pvariable(ID(f"{font}_engine", True, type=FontEngine), MockObj(font))
|
cg.new_Pvariable(ID(f"{font}_engine", True, type=FontEngine), MockObj(font))
|
||||||
default_font = config[df.CONF_DEFAULT_FONT]
|
default_font = config[df.CONF_DEFAULT_FONT]
|
||||||
if default_font not in helpers.lv_fonts_used:
|
if not lvalid.is_lv_font(default_font):
|
||||||
add_define(
|
add_define(
|
||||||
"LV_FONT_CUSTOM_DECLARE", f"LV_FONT_DECLARE(*{df.DEFAULT_ESPHOME_FONT})"
|
"LV_FONT_CUSTOM_DECLARE", f"LV_FONT_DECLARE(*{df.DEFAULT_ESPHOME_FONT})"
|
||||||
)
|
)
|
||||||
|
@ -161,12 +165,15 @@ async def to_code(config):
|
||||||
True,
|
True,
|
||||||
type=lv_font_t.operator("ptr").operator("const"),
|
type=lv_font_t.operator("ptr").operator("const"),
|
||||||
)
|
)
|
||||||
cg.new_variable(globfont_id, MockObj(default_font))
|
cg.new_variable(
|
||||||
|
globfont_id, MockObj(await lvalid.lv_font.process(default_font))
|
||||||
|
)
|
||||||
add_define("LV_FONT_DEFAULT", df.DEFAULT_ESPHOME_FONT)
|
add_define("LV_FONT_DEFAULT", df.DEFAULT_ESPHOME_FONT)
|
||||||
else:
|
else:
|
||||||
add_define("LV_FONT_DEFAULT", default_font)
|
add_define("LV_FONT_DEFAULT", await lvalid.lv_font.process(default_font))
|
||||||
|
|
||||||
with LvContext():
|
with LvContext():
|
||||||
|
await touchscreens_to_code(lv_component, config)
|
||||||
await set_obj_properties(lv_scr_act, config)
|
await set_obj_properties(lv_scr_act, config)
|
||||||
await add_widgets(lv_scr_act, config)
|
await add_widgets(lv_scr_act, config)
|
||||||
Widget.set_completed()
|
Widget.set_completed()
|
||||||
|
@ -190,7 +197,7 @@ FINAL_VALIDATE_SCHEMA = final_validation
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
cv.polling_component_schema("1s")
|
cv.polling_component_schema("1s")
|
||||||
.extend(obj_schema("obj"))
|
.extend(obj_schema(obj_spec))
|
||||||
.extend(
|
.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent),
|
cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent),
|
||||||
|
@ -207,6 +214,7 @@ CONFIG_SCHEMA = (
|
||||||
),
|
),
|
||||||
cv.Optional(df.CONF_WIDGETS): cv.ensure_list(WIDGET_SCHEMA),
|
cv.Optional(df.CONF_WIDGETS): cv.ensure_list(WIDGET_SCHEMA),
|
||||||
cv.Optional(df.CONF_TRANSPARENCY_KEY, default=0x000400): lvalid.lv_color,
|
cv.Optional(df.CONF_TRANSPARENCY_KEY, default=0x000400): lvalid.lv_color,
|
||||||
|
cv.GenerateID(df.CONF_TOUCHSCREENS): touchscreen_schema,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
).add_extra(cv.has_at_least_one_key(CONF_PAGES, df.CONF_WIDGETS))
|
).add_extra(cv.has_at_least_one_key(CONF_PAGES, df.CONF_WIDGETS))
|
||||||
|
|
25
esphome/components/lvgl/btn.py
Normal file
25
esphome/components/lvgl/btn.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from esphome.const import CONF_BUTTON
|
||||||
|
from esphome.cpp_generator import MockObjClass
|
||||||
|
|
||||||
|
from .defines import CONF_MAIN
|
||||||
|
from .types import LvBoolean, WidgetType
|
||||||
|
|
||||||
|
|
||||||
|
class BtnType(WidgetType):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(CONF_BUTTON, LvBoolean("lv_btn_t"), (CONF_MAIN,))
|
||||||
|
|
||||||
|
async def to_code(self, w, config):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||||
|
"""
|
||||||
|
LVGL 8 calls buttons `btn`
|
||||||
|
"""
|
||||||
|
return f"lv_btn_create({parent})"
|
||||||
|
|
||||||
|
def get_uses(self):
|
||||||
|
return ("btn",)
|
||||||
|
|
||||||
|
|
||||||
|
btn_spec = BtnType()
|
|
@ -446,6 +446,7 @@ CONF_TILE_ID = "tile_id"
|
||||||
CONF_TILES = "tiles"
|
CONF_TILES = "tiles"
|
||||||
CONF_TITLE = "title"
|
CONF_TITLE = "title"
|
||||||
CONF_TOP_LAYER = "top_layer"
|
CONF_TOP_LAYER = "top_layer"
|
||||||
|
CONF_TOUCHSCREENS = "touchscreens"
|
||||||
CONF_TRANSPARENCY_KEY = "transparency_key"
|
CONF_TRANSPARENCY_KEY = "transparency_key"
|
||||||
CONF_THEME = "theme"
|
CONF_THEME = "theme"
|
||||||
CONF_VISIBLE_ROW_COUNT = "visible_row_count"
|
CONF_VISIBLE_ROW_COUNT = "visible_row_count"
|
||||||
|
@ -474,14 +475,8 @@ LV_KEYS = LvConstant(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# list of widgets and the parts allowed
|
|
||||||
WIDGET_PARTS = {
|
|
||||||
CONF_LABEL: (CONF_MAIN, CONF_SCROLLBAR, CONF_SELECTED),
|
|
||||||
CONF_OBJ: (CONF_MAIN,),
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFAULT_ESPHOME_FONT = "esphome_lv_default_font"
|
DEFAULT_ESPHOME_FONT = "esphome_lv_default_font"
|
||||||
|
|
||||||
|
|
||||||
def join_enums(enums, prefix=""):
|
def join_enums(enums, prefix=""):
|
||||||
return "|".join(f"(int){prefix}{e.upper()}" for e in enums)
|
return ConstantLiteral("|".join(f"(int){prefix}{e.upper()}" for e in enums))
|
||||||
|
|
|
@ -22,7 +22,6 @@ def add_lv_use(*names):
|
||||||
|
|
||||||
lv_fonts_used = set()
|
lv_fonts_used = set()
|
||||||
esphome_fonts_used = set()
|
esphome_fonts_used = set()
|
||||||
REQUIRED_COMPONENTS = {}
|
|
||||||
lvgl_components_required = set()
|
lvgl_components_required = set()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,27 @@
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
|
||||||
from .defines import CONF_LABEL, CONF_LONG_MODE, CONF_RECOLOR, CONF_TEXT, LV_LONG_MODES
|
from .defines import (
|
||||||
|
CONF_LABEL,
|
||||||
|
CONF_LONG_MODE,
|
||||||
|
CONF_MAIN,
|
||||||
|
CONF_RECOLOR,
|
||||||
|
CONF_SCROLLBAR,
|
||||||
|
CONF_SELECTED,
|
||||||
|
CONF_TEXT,
|
||||||
|
LV_LONG_MODES,
|
||||||
|
)
|
||||||
from .lv_validation import lv_bool, lv_text
|
from .lv_validation import lv_bool, lv_text
|
||||||
from .schemas import TEXT_SCHEMA
|
from .schemas import TEXT_SCHEMA
|
||||||
from .types import lv_label_t
|
from .types import LvText, WidgetType
|
||||||
from .widget import Widget, WidgetType
|
from .widget import Widget
|
||||||
|
|
||||||
|
|
||||||
class LabelType(WidgetType):
|
class LabelType(WidgetType):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
CONF_LABEL,
|
CONF_LABEL,
|
||||||
|
LvText("lv_label_t"),
|
||||||
|
(CONF_MAIN, CONF_SCROLLBAR, CONF_SELECTED),
|
||||||
TEXT_SCHEMA.extend(
|
TEXT_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
cv.Optional(CONF_RECOLOR): lv_bool,
|
cv.Optional(CONF_RECOLOR): lv_bool,
|
||||||
|
@ -19,10 +30,6 @@ class LabelType(WidgetType):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def w_type(self):
|
|
||||||
return lv_label_t
|
|
||||||
|
|
||||||
async def to_code(self, w: Widget, config):
|
async def to_code(self, w: Widget, config):
|
||||||
"""For a text object, create and set text"""
|
"""For a text object, create and set text"""
|
||||||
if value := config.get(CONF_TEXT):
|
if value := config.get(CONF_TEXT):
|
||||||
|
|
|
@ -8,6 +8,7 @@ import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ARGS, CONF_COLOR, CONF_FORMAT
|
from esphome.const import CONF_ARGS, CONF_COLOR, CONF_FORMAT
|
||||||
from esphome.core import HexInt
|
from esphome.core import HexInt
|
||||||
from esphome.cpp_generator import MockObj
|
from esphome.cpp_generator import MockObj
|
||||||
|
from esphome.cpp_types import uint32
|
||||||
from esphome.helpers import cpp_string_escape
|
from esphome.helpers import cpp_string_escape
|
||||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||||
|
|
||||||
|
@ -23,6 +24,28 @@ from .lvcode import ConstantLiteral, lv_expr
|
||||||
from .types import lv_font_t
|
from .types import lv_font_t
|
||||||
|
|
||||||
|
|
||||||
|
def literal_mapper(value, args=()):
|
||||||
|
if isinstance(value, str):
|
||||||
|
return ConstantLiteral(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
opacity_consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
|
||||||
|
|
||||||
|
|
||||||
|
@schema_extractor("one_of")
|
||||||
|
def opacity_validator(value):
|
||||||
|
if value == SCHEMA_EXTRACT:
|
||||||
|
return opacity_consts.choices
|
||||||
|
value = cv.Any(cv.percentage, opacity_consts.one_of)(value)
|
||||||
|
if isinstance(value, float):
|
||||||
|
return int(value * 255)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
opacity = LValidator(opacity_validator, uint32, retmapper=literal_mapper)
|
||||||
|
|
||||||
|
|
||||||
@schema_extractor("one_of")
|
@schema_extractor("one_of")
|
||||||
def color(value):
|
def color(value):
|
||||||
if value == SCHEMA_EXTRACT:
|
if value == SCHEMA_EXTRACT:
|
||||||
|
@ -43,16 +66,24 @@ def color_retmapper(value):
|
||||||
return lv_expr.color_from(MockObj(value))
|
return lv_expr.color_from(MockObj(value))
|
||||||
|
|
||||||
|
|
||||||
def pixels_or_percent(value):
|
lv_color = LValidator(color, ty.lv_color_t, retmapper=color_retmapper)
|
||||||
|
|
||||||
|
|
||||||
|
def pixels_or_percent_validator(value):
|
||||||
"""A length in one axis - either a number (pixels) or a percentage"""
|
"""A length in one axis - either a number (pixels) or a percentage"""
|
||||||
if value == SCHEMA_EXTRACT:
|
if value == SCHEMA_EXTRACT:
|
||||||
return ["pixels", "..%"]
|
return ["pixels", "..%"]
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
return str(cv.int_(value))
|
return cv.int_(value)
|
||||||
# Will throw an exception if not a percentage.
|
# Will throw an exception if not a percentage.
|
||||||
return f"lv_pct({int(cv.percentage(value) * 100)})"
|
return f"lv_pct({int(cv.percentage(value) * 100)})"
|
||||||
|
|
||||||
|
|
||||||
|
pixels_or_percent = LValidator(
|
||||||
|
pixels_or_percent_validator, uint32, retmapper=literal_mapper
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def zoom(value):
|
def zoom(value):
|
||||||
value = cv.float_range(0.1, 10.0)(value)
|
value = cv.float_range(0.1, 10.0)(value)
|
||||||
return int(value * 256)
|
return int(value * 256)
|
||||||
|
@ -68,7 +99,7 @@ def angle(value):
|
||||||
|
|
||||||
|
|
||||||
@schema_extractor("one_of")
|
@schema_extractor("one_of")
|
||||||
def size(value):
|
def size_validator(value):
|
||||||
"""A size in one axis - one of "size_content", a number (pixels) or a percentage"""
|
"""A size in one axis - one of "size_content", a number (pixels) or a percentage"""
|
||||||
if value == SCHEMA_EXTRACT:
|
if value == SCHEMA_EXTRACT:
|
||||||
return ["size_content", "pixels", "..%"]
|
return ["size_content", "pixels", "..%"]
|
||||||
|
@ -79,28 +110,42 @@ def size(value):
|
||||||
return "LV_SIZE_CONTENT"
|
return "LV_SIZE_CONTENT"
|
||||||
raise cv.Invalid("must be 'size_content', a pixel position or a percentage")
|
raise cv.Invalid("must be 'size_content', a pixel position or a percentage")
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
return str(cv.int_(value))
|
return cv.int_(value)
|
||||||
# Will throw an exception if not a percentage.
|
# Will throw an exception if not a percentage.
|
||||||
return f"lv_pct({int(cv.percentage(value) * 100)})"
|
return f"lv_pct({int(cv.percentage(value) * 100)})"
|
||||||
|
|
||||||
|
|
||||||
|
size = LValidator(size_validator, uint32, retmapper=literal_mapper)
|
||||||
|
|
||||||
|
radius_consts = LvConstant("LV_RADIUS_", "CIRCLE")
|
||||||
|
|
||||||
|
|
||||||
@schema_extractor("one_of")
|
@schema_extractor("one_of")
|
||||||
def opacity(value):
|
def radius_validator(value):
|
||||||
consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
|
|
||||||
if value == SCHEMA_EXTRACT:
|
if value == SCHEMA_EXTRACT:
|
||||||
return consts.choices
|
return radius_consts.choices
|
||||||
value = cv.Any(cv.percentage, consts.one_of)(value)
|
value = cv.Any(size, cv.percentage, radius_consts.one_of)(value)
|
||||||
if isinstance(value, float):
|
if isinstance(value, float):
|
||||||
return int(value * 255)
|
return int(value * 255)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def id_name(value):
|
||||||
|
if value == SCHEMA_EXTRACT:
|
||||||
|
return "id"
|
||||||
|
return cv.validate_id_name(value)
|
||||||
|
|
||||||
|
|
||||||
|
radius = LValidator(radius_validator, uint32, retmapper=literal_mapper)
|
||||||
|
|
||||||
|
|
||||||
def stop_value(value):
|
def stop_value(value):
|
||||||
return cv.int_range(0, 255)(value)
|
return cv.int_range(0, 255)(value)
|
||||||
|
|
||||||
|
|
||||||
lv_color = LValidator(color, ty.lv_color_t, retmapper=color_retmapper)
|
lv_bool = LValidator(
|
||||||
lv_bool = LValidator(cv.boolean, cg.bool_, BinarySensor, "get_state()")
|
cv.boolean, cg.bool_, BinarySensor, "get_state()", retmapper=literal_mapper
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def lvms_validator_(value):
|
def lvms_validator_(value):
|
||||||
|
@ -145,26 +190,32 @@ lv_float = LValidator(cv.float_, cg.float_, Sensor, "get_state()")
|
||||||
lv_int = LValidator(cv.int_, cg.int_, Sensor, "get_state()")
|
lv_int = LValidator(cv.int_, cg.int_, Sensor, "get_state()")
|
||||||
|
|
||||||
|
|
||||||
|
def is_lv_font(font):
|
||||||
|
return isinstance(font, str) and font.lower() in LV_FONTS
|
||||||
|
|
||||||
|
|
||||||
class LvFont(LValidator):
|
class LvFont(LValidator):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
def lv_builtin_font(value):
|
def lv_builtin_font(value):
|
||||||
fontval = cv.one_of(*LV_FONTS, lower=True)(value)
|
fontval = cv.one_of(*LV_FONTS, lower=True)(value)
|
||||||
lv_fonts_used.add(fontval)
|
lv_fonts_used.add(fontval)
|
||||||
return "&lv_font_" + fontval
|
return fontval
|
||||||
|
|
||||||
def validator(value):
|
def validator(value):
|
||||||
if value == SCHEMA_EXTRACT:
|
if value == SCHEMA_EXTRACT:
|
||||||
return LV_FONTS
|
return LV_FONTS
|
||||||
if isinstance(value, str) and value.lower() in LV_FONTS:
|
if is_lv_font(value):
|
||||||
return lv_builtin_font(value)
|
return lv_builtin_font(value)
|
||||||
fontval = cv.use_id(Font)(value)
|
fontval = cv.use_id(Font)(value)
|
||||||
esphome_fonts_used.add(fontval)
|
esphome_fonts_used.add(fontval)
|
||||||
return requires_component("font")(f"{fontval}_engine->get_lv_font()")
|
return requires_component("font")(fontval)
|
||||||
|
|
||||||
super().__init__(validator, lv_font_t)
|
super().__init__(validator, lv_font_t)
|
||||||
|
|
||||||
async def process(self, value, args=()):
|
async def process(self, value, args=()):
|
||||||
return ConstantLiteral(value)
|
if is_lv_font(value):
|
||||||
|
return ConstantLiteral(f"&lv_font_{value}")
|
||||||
|
return ConstantLiteral(f"{value}_engine->get_lv_font()")
|
||||||
|
|
||||||
|
|
||||||
lv_font = LvFont()
|
lv_font = LvFont()
|
||||||
|
|
|
@ -38,7 +38,9 @@ void LvglComponent::setup() {
|
||||||
auto buf_bytes = buffer_pixels * LV_COLOR_DEPTH / 8;
|
auto buf_bytes = buffer_pixels * LV_COLOR_DEPTH / 8;
|
||||||
auto *buf = lv_custom_mem_alloc(buf_bytes);
|
auto *buf = lv_custom_mem_alloc(buf_bytes);
|
||||||
if (buf == nullptr) {
|
if (buf == nullptr) {
|
||||||
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
||||||
ESP_LOGE(TAG, "Malloc failed to allocate %zu bytes", buf_bytes);
|
ESP_LOGE(TAG, "Malloc failed to allocate %zu bytes", buf_bytes);
|
||||||
|
#endif
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
this->status_set_error("Memory allocation failure");
|
this->status_set_error("Memory allocation failure");
|
||||||
return;
|
return;
|
||||||
|
@ -85,7 +87,9 @@ size_t lv_millis(void) { return esphome::millis(); }
|
||||||
void *lv_custom_mem_alloc(size_t size) {
|
void *lv_custom_mem_alloc(size_t size) {
|
||||||
auto *ptr = malloc(size); // NOLINT
|
auto *ptr = malloc(size); // NOLINT
|
||||||
if (ptr == nullptr) {
|
if (ptr == nullptr) {
|
||||||
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
||||||
esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
|
esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +106,9 @@ void *lv_custom_mem_alloc(size_t size) {
|
||||||
ptr = heap_caps_malloc(size, cap_bits);
|
ptr = heap_caps_malloc(size, cap_bits);
|
||||||
}
|
}
|
||||||
if (ptr == nullptr) {
|
if (ptr == nullptr) {
|
||||||
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
||||||
esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
|
esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
|
||||||
|
#endif
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
||||||
|
|
|
@ -18,23 +18,27 @@
|
||||||
#ifdef USE_LVGL_FONT
|
#ifdef USE_LVGL_FONT
|
||||||
#include "esphome/components/font/font.h"
|
#include "esphome/components/font/font.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_LVGL_TOUCHSCREEN
|
||||||
|
#include "esphome/components/touchscreen/touchscreen.h"
|
||||||
|
#endif // USE_LVGL_TOUCHSCREEN
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace lvgl {
|
namespace lvgl {
|
||||||
|
|
||||||
extern lv_event_code_t lv_custom_event; // NOLINT
|
extern lv_event_code_t lv_custom_event; // NOLINT
|
||||||
#ifdef USE_LVGL_COLOR
|
#ifdef USE_LVGL_COLOR
|
||||||
static lv_color_t lv_color_from(Color color) { return lv_color_make(color.red, color.green, color.blue); }
|
inline lv_color_t lv_color_from(Color color) { return lv_color_make(color.red, color.green, color.blue); }
|
||||||
#endif
|
#endif // USE_LVGL_COLOR
|
||||||
#if LV_COLOR_DEPTH == 16
|
#if LV_COLOR_DEPTH == 16
|
||||||
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_565;
|
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_565;
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_888;
|
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_888;
|
||||||
#else
|
#else // LV_COLOR_DEPTH
|
||||||
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_332;
|
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_332;
|
||||||
#endif
|
#endif // LV_COLOR_DEPTH
|
||||||
|
|
||||||
// Parent class for things that wrap an LVGL object
|
// Parent class for things that wrap an LVGL object
|
||||||
class LvCompound {
|
class LvCompound final {
|
||||||
public:
|
public:
|
||||||
virtual void set_obj(lv_obj_t *lv_obj) { this->obj = lv_obj; }
|
virtual void set_obj(lv_obj_t *lv_obj) { this->obj = lv_obj; }
|
||||||
lv_obj_t *obj{};
|
lv_obj_t *obj{};
|
||||||
|
@ -99,6 +103,14 @@ class LvglComponent : public PollingComponent {
|
||||||
void set_full_refresh(bool full_refresh) { this->full_refresh_ = full_refresh; }
|
void set_full_refresh(bool full_refresh) { this->full_refresh_ = full_refresh; }
|
||||||
void set_buffer_frac(size_t frac) { this->buffer_frac_ = frac; }
|
void set_buffer_frac(size_t frac) { this->buffer_frac_ = frac; }
|
||||||
lv_disp_t *get_disp() { return this->disp_; }
|
lv_disp_t *get_disp() { return this->disp_; }
|
||||||
|
void set_paused(bool paused, bool show_snow) {
|
||||||
|
this->paused_ = paused;
|
||||||
|
if (!paused && lv_scr_act() != nullptr) {
|
||||||
|
lv_disp_trig_activity(this->disp_); // resets the inactivity time
|
||||||
|
lv_obj_invalidate(lv_scr_act());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool is_paused() const { return this->paused_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void draw_buffer_(const lv_area_t *area, const uint8_t *ptr);
|
void draw_buffer_(const lv_area_t *area, const uint8_t *ptr);
|
||||||
|
@ -107,13 +119,48 @@ class LvglComponent : public PollingComponent {
|
||||||
lv_disp_draw_buf_t draw_buf_{};
|
lv_disp_draw_buf_t draw_buf_{};
|
||||||
lv_disp_drv_t disp_drv_{};
|
lv_disp_drv_t disp_drv_{};
|
||||||
lv_disp_t *disp_{};
|
lv_disp_t *disp_{};
|
||||||
|
bool paused_{};
|
||||||
|
|
||||||
std::vector<std::function<void(lv_disp_t *)>> init_lambdas_;
|
std::vector<std::function<void(lv_disp_t *)>> init_lambdas_;
|
||||||
size_t buffer_frac_{1};
|
size_t buffer_frac_{1};
|
||||||
bool full_refresh_{};
|
bool full_refresh_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_LVGL_TOUCHSCREEN
|
||||||
|
class LVTouchListener : public touchscreen::TouchListener, public Parented<LvglComponent> {
|
||||||
|
public:
|
||||||
|
LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time) {
|
||||||
|
lv_indev_drv_init(&this->drv_);
|
||||||
|
this->drv_.long_press_repeat_time = long_press_repeat_time;
|
||||||
|
this->drv_.long_press_time = long_press_time;
|
||||||
|
this->drv_.type = LV_INDEV_TYPE_POINTER;
|
||||||
|
this->drv_.user_data = this;
|
||||||
|
this->drv_.read_cb = [](lv_indev_drv_t *d, lv_indev_data_t *data) {
|
||||||
|
auto *l = static_cast<LVTouchListener *>(d->user_data);
|
||||||
|
if (l->touch_pressed_) {
|
||||||
|
data->point.x = l->touch_point_.x;
|
||||||
|
data->point.y = l->touch_point_.y;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else {
|
||||||
|
data->state = LV_INDEV_STATE_RELEASED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
void update(const touchscreen::TouchPoints_t &tpoints) override {
|
||||||
|
this->touch_pressed_ = !this->parent_->is_paused() && !tpoints.empty();
|
||||||
|
if (this->touch_pressed_)
|
||||||
|
this->touch_point_ = tpoints[0];
|
||||||
|
}
|
||||||
|
void release() override { touch_pressed_ = false; }
|
||||||
|
lv_indev_drv_t *get_drv() { return &this->drv_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
lv_indev_drv_t drv_{};
|
||||||
|
touchscreen::TouchPoint touch_point_{};
|
||||||
|
bool touch_pressed_{};
|
||||||
|
};
|
||||||
|
#endif // USE_LVGL_TOUCHSCREEN
|
||||||
} // namespace lvgl
|
} // namespace lvgl
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
#endif
|
#endif // USE_LVGL
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from .defines import CONF_OBJ
|
from .defines import CONF_MAIN, CONF_OBJ
|
||||||
from .types import lv_obj_t
|
from .types import WidgetType, lv_obj_t
|
||||||
from .widget import WidgetType
|
|
||||||
|
|
||||||
|
|
||||||
class ObjType(WidgetType):
|
class ObjType(WidgetType):
|
||||||
|
@ -9,11 +8,7 @@ class ObjType(WidgetType):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(CONF_OBJ, schema={}, modify_schema={})
|
super().__init__(CONF_OBJ, lv_obj_t, (CONF_MAIN,), schema={}, modify_schema={})
|
||||||
|
|
||||||
@property
|
|
||||||
def w_type(self):
|
|
||||||
return lv_obj_t
|
|
||||||
|
|
||||||
async def to_code(self, w, config):
|
async def to_code(self, w, config):
|
||||||
return []
|
return []
|
||||||
|
|
|
@ -3,15 +3,9 @@ from esphome.const import CONF_ARGS, CONF_FORMAT, CONF_ID, CONF_STATE, CONF_TYPE
|
||||||
from esphome.schema_extractors import SCHEMA_EXTRACT
|
from esphome.schema_extractors import SCHEMA_EXTRACT
|
||||||
|
|
||||||
from . import defines as df, lv_validation as lvalid, types as ty
|
from . import defines as df, lv_validation as lvalid, types as ty
|
||||||
from .defines import WIDGET_PARTS
|
from .helpers import add_lv_use, requires_component, validate_printf
|
||||||
from .helpers import (
|
|
||||||
REQUIRED_COMPONENTS,
|
|
||||||
add_lv_use,
|
|
||||||
requires_component,
|
|
||||||
validate_printf,
|
|
||||||
)
|
|
||||||
from .lv_validation import lv_font
|
from .lv_validation import lv_font
|
||||||
from .types import WIDGET_TYPES, get_widget_type
|
from .types import WIDGET_TYPES, WidgetType
|
||||||
|
|
||||||
# A schema for text properties
|
# A schema for text properties
|
||||||
TEXT_SCHEMA = cv.Schema(
|
TEXT_SCHEMA = cv.Schema(
|
||||||
|
@ -46,9 +40,9 @@ STYLE_PROPS = {
|
||||||
"bg_dither_mode": df.LvConstant("LV_DITHER_", "NONE", "ORDERED", "ERR_DIFF").one_of,
|
"bg_dither_mode": df.LvConstant("LV_DITHER_", "NONE", "ORDERED", "ERR_DIFF").one_of,
|
||||||
"bg_grad_dir": df.LvConstant("LV_GRAD_DIR_", "NONE", "HOR", "VER").one_of,
|
"bg_grad_dir": df.LvConstant("LV_GRAD_DIR_", "NONE", "HOR", "VER").one_of,
|
||||||
"bg_grad_stop": lvalid.stop_value,
|
"bg_grad_stop": lvalid.stop_value,
|
||||||
"bg_img_opa": lvalid.opacity,
|
"bg_image_opa": lvalid.opacity,
|
||||||
"bg_img_recolor": lvalid.lv_color,
|
"bg_image_recolor": lvalid.lv_color,
|
||||||
"bg_img_recolor_opa": lvalid.opacity,
|
"bg_image_recolor_opa": lvalid.opacity,
|
||||||
"bg_main_stop": lvalid.stop_value,
|
"bg_main_stop": lvalid.stop_value,
|
||||||
"bg_opa": lvalid.opacity,
|
"bg_opa": lvalid.opacity,
|
||||||
"border_color": lvalid.lv_color,
|
"border_color": lvalid.lv_color,
|
||||||
|
@ -60,8 +54,8 @@ STYLE_PROPS = {
|
||||||
"border_width": cv.positive_int,
|
"border_width": cv.positive_int,
|
||||||
"clip_corner": lvalid.lv_bool,
|
"clip_corner": lvalid.lv_bool,
|
||||||
"height": lvalid.size,
|
"height": lvalid.size,
|
||||||
"img_recolor": lvalid.lv_color,
|
"image_recolor": lvalid.lv_color,
|
||||||
"img_recolor_opa": lvalid.opacity,
|
"image_recolor_opa": lvalid.opacity,
|
||||||
"line_width": cv.positive_int,
|
"line_width": cv.positive_int,
|
||||||
"line_dash_width": cv.positive_int,
|
"line_dash_width": cv.positive_int,
|
||||||
"line_dash_gap": cv.positive_int,
|
"line_dash_gap": cv.positive_int,
|
||||||
|
@ -108,12 +102,21 @@ STYLE_PROPS = {
|
||||||
"max_width": lvalid.pixels_or_percent,
|
"max_width": lvalid.pixels_or_percent,
|
||||||
"min_height": lvalid.pixels_or_percent,
|
"min_height": lvalid.pixels_or_percent,
|
||||||
"min_width": lvalid.pixels_or_percent,
|
"min_width": lvalid.pixels_or_percent,
|
||||||
"radius": cv.Any(lvalid.size, df.LvConstant("LV_RADIUS_", "CIRCLE").one_of),
|
"radius": lvalid.radius,
|
||||||
"width": lvalid.size,
|
"width": lvalid.size,
|
||||||
"x": lvalid.pixels_or_percent,
|
"x": lvalid.pixels_or_percent,
|
||||||
"y": lvalid.pixels_or_percent,
|
"y": lvalid.pixels_or_percent,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STYLE_REMAP = {
|
||||||
|
"bg_image_opa": "bg_img_opa",
|
||||||
|
"bg_image_recolor": "bg_img_recolor",
|
||||||
|
"bg_image_recolor_opa": "bg_img_recolor_opa",
|
||||||
|
"bg_image_src": "bg_img_src",
|
||||||
|
"image_recolor": "img_recolor",
|
||||||
|
"image_recolor_opa": "img_recolor_opa",
|
||||||
|
}
|
||||||
|
|
||||||
# Complete object style schema
|
# Complete object style schema
|
||||||
STYLE_SCHEMA = cv.Schema({cv.Optional(k): v for k, v in STYLE_PROPS.items()}).extend(
|
STYLE_SCHEMA = cv.Schema({cv.Optional(k): v for k, v in STYLE_PROPS.items()}).extend(
|
||||||
{
|
{
|
||||||
|
@ -132,25 +135,23 @@ SET_STATE_SCHEMA = cv.Schema(
|
||||||
{cv.Optional(state): lvalid.lv_bool for state in df.STATES}
|
{cv.Optional(state): lvalid.lv_bool for state in df.STATES}
|
||||||
)
|
)
|
||||||
# Setting object flags
|
# Setting object flags
|
||||||
FLAG_SCHEMA = cv.Schema({cv.Optional(flag): cv.boolean for flag in df.OBJ_FLAGS})
|
FLAG_SCHEMA = cv.Schema({cv.Optional(flag): lvalid.lv_bool for flag in df.OBJ_FLAGS})
|
||||||
FLAG_LIST = cv.ensure_list(df.LvConstant("LV_OBJ_FLAG_", *df.OBJ_FLAGS).one_of)
|
FLAG_LIST = cv.ensure_list(df.LvConstant("LV_OBJ_FLAG_", *df.OBJ_FLAGS).one_of)
|
||||||
|
|
||||||
|
|
||||||
def part_schema(widget_type):
|
def part_schema(widget_type: WidgetType):
|
||||||
"""
|
"""
|
||||||
Generate a schema for the various parts (e.g. main:, indicator:) of a widget type
|
Generate a schema for the various parts (e.g. main:, indicator:) of a widget type
|
||||||
:param widget_type: The type of widget to generate for
|
:param widget_type: The type of widget to generate for
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
parts = WIDGET_PARTS.get(widget_type)
|
parts = widget_type.parts
|
||||||
if parts is None:
|
|
||||||
parts = (df.CONF_MAIN,)
|
|
||||||
return cv.Schema({cv.Optional(part): STATE_SCHEMA for part in parts}).extend(
|
return cv.Schema({cv.Optional(part): STATE_SCHEMA for part in parts}).extend(
|
||||||
STATE_SCHEMA
|
STATE_SCHEMA
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def obj_schema(widget_type: str):
|
def obj_schema(widget_type: WidgetType):
|
||||||
"""
|
"""
|
||||||
Create a schema for a widget type itself i.e. no allowance for children
|
Create a schema for a widget type itself i.e. no allowance for children
|
||||||
:param widget_type:
|
:param widget_type:
|
||||||
|
@ -187,13 +188,12 @@ STYLED_TEXT_SCHEMA = cv.maybe_simple_value(
|
||||||
STYLE_SCHEMA.extend(TEXT_SCHEMA), key=df.CONF_TEXT
|
STYLE_SCHEMA.extend(TEXT_SCHEMA), key=df.CONF_TEXT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
ALL_STYLES = {
|
ALL_STYLES = {
|
||||||
**STYLE_PROPS,
|
**STYLE_PROPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def container_validator(schema, widget_type):
|
def container_validator(schema, widget_type: WidgetType):
|
||||||
"""
|
"""
|
||||||
Create a validator for a container given the widget type
|
Create a validator for a container given the widget type
|
||||||
:param schema: Base schema to extend
|
:param schema: Base schema to extend
|
||||||
|
@ -203,13 +203,16 @@ def container_validator(schema, widget_type):
|
||||||
|
|
||||||
def validator(value):
|
def validator(value):
|
||||||
result = schema
|
result = schema
|
||||||
if w_sch := WIDGET_TYPES[widget_type].schema:
|
if w_sch := widget_type.schema:
|
||||||
result = result.extend(w_sch)
|
result = result.extend(w_sch)
|
||||||
if value and (layout := value.get(df.CONF_LAYOUT)):
|
if value and (layout := value.get(df.CONF_LAYOUT)):
|
||||||
if not isinstance(layout, dict):
|
if not isinstance(layout, dict):
|
||||||
raise cv.Invalid("Layout value must be a dict")
|
raise cv.Invalid("Layout value must be a dict")
|
||||||
ltype = layout.get(CONF_TYPE)
|
ltype = layout.get(CONF_TYPE)
|
||||||
add_lv_use(ltype)
|
add_lv_use(ltype)
|
||||||
|
result = result.extend(
|
||||||
|
{cv.Optional(df.CONF_WIDGETS): cv.ensure_list(any_widget_schema())}
|
||||||
|
)
|
||||||
if value == SCHEMA_EXTRACT:
|
if value == SCHEMA_EXTRACT:
|
||||||
return result
|
return result
|
||||||
return result(value)
|
return result(value)
|
||||||
|
@ -217,7 +220,7 @@ def container_validator(schema, widget_type):
|
||||||
return validator
|
return validator
|
||||||
|
|
||||||
|
|
||||||
def container_schema(widget_type, extras=None):
|
def container_schema(widget_type: WidgetType, extras=None):
|
||||||
"""
|
"""
|
||||||
Create a schema for a container widget of a given type. All obj properties are available, plus
|
Create a schema for a container widget of a given type. All obj properties are available, plus
|
||||||
the extras passed in, plus any defined for the specific widget being specified.
|
the extras passed in, plus any defined for the specific widget being specified.
|
||||||
|
@ -225,15 +228,16 @@ def container_schema(widget_type, extras=None):
|
||||||
:param extras: Additional options to be made available, e.g. layout properties for children
|
:param extras: Additional options to be made available, e.g. layout properties for children
|
||||||
:return: The schema for this type of widget.
|
:return: The schema for this type of widget.
|
||||||
"""
|
"""
|
||||||
lv_type = get_widget_type(widget_type)
|
schema = obj_schema(widget_type).extend(
|
||||||
schema = obj_schema(widget_type).extend({cv.GenerateID(): cv.declare_id(lv_type)})
|
{cv.GenerateID(): cv.declare_id(widget_type.w_type)}
|
||||||
|
)
|
||||||
if extras:
|
if extras:
|
||||||
schema = schema.extend(extras)
|
schema = schema.extend(extras)
|
||||||
# Delayed evaluation for recursion
|
# Delayed evaluation for recursion
|
||||||
return container_validator(schema, widget_type)
|
return container_validator(schema, widget_type)
|
||||||
|
|
||||||
|
|
||||||
def widget_schema(widget_type, extras=None):
|
def widget_schema(widget_type: WidgetType, extras=None):
|
||||||
"""
|
"""
|
||||||
Create a schema for a given widget type
|
Create a schema for a given widget type
|
||||||
:param widget_type: The name of the widget
|
:param widget_type: The name of the widget
|
||||||
|
@ -241,9 +245,9 @@ def widget_schema(widget_type, extras=None):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
validator = container_schema(widget_type, extras=extras)
|
validator = container_schema(widget_type, extras=extras)
|
||||||
if required := REQUIRED_COMPONENTS.get(widget_type):
|
if required := widget_type.required_component:
|
||||||
validator = cv.All(validator, requires_component(required))
|
validator = cv.All(validator, requires_component(required))
|
||||||
return cv.Exclusive(widget_type, df.CONF_WIDGETS), validator
|
return cv.Exclusive(widget_type.name, df.CONF_WIDGETS), validator
|
||||||
|
|
||||||
|
|
||||||
# All widget schemas must be defined before this is called.
|
# All widget schemas must be defined before this is called.
|
||||||
|
@ -257,4 +261,4 @@ def any_widget_schema(extras=None):
|
||||||
:param extras: Additional schema to be applied to each generated one
|
:param extras: Additional schema to be applied to each generated one
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return cv.Any(dict(widget_schema(wt, extras) for wt in WIDGET_PARTS))
|
return cv.Any(dict(widget_schema(wt, extras) for wt in WIDGET_TYPES.values()))
|
||||||
|
|
46
esphome/components/lvgl/touchscreens.py
Normal file
46
esphome/components/lvgl/touchscreens.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components.touchscreen import CONF_TOUCHSCREEN_ID, Touchscreen
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
from esphome.core import CORE, TimePeriod
|
||||||
|
|
||||||
|
from .defines import (
|
||||||
|
CONF_LONG_PRESS_REPEAT_TIME,
|
||||||
|
CONF_LONG_PRESS_TIME,
|
||||||
|
CONF_TOUCHSCREENS,
|
||||||
|
)
|
||||||
|
from .helpers import lvgl_components_required
|
||||||
|
from .lv_validation import lv_milliseconds
|
||||||
|
from .lvcode import lv
|
||||||
|
from .types import LVTouchListener
|
||||||
|
|
||||||
|
PRESS_TIME = cv.All(lv_milliseconds, cv.Range(max=TimePeriod(milliseconds=65535)))
|
||||||
|
CONF_TOUCHSCREEN = "touchscreen"
|
||||||
|
TOUCHSCREENS_CONFIG = cv.maybe_simple_value(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_TOUCHSCREEN_ID): cv.use_id(Touchscreen),
|
||||||
|
cv.Optional(CONF_LONG_PRESS_TIME, default="400ms"): PRESS_TIME,
|
||||||
|
cv.Optional(CONF_LONG_PRESS_REPEAT_TIME, default="100ms"): PRESS_TIME,
|
||||||
|
cv.GenerateID(): cv.declare_id(LVTouchListener),
|
||||||
|
},
|
||||||
|
key=CONF_TOUCHSCREEN_ID,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def touchscreen_schema(config):
|
||||||
|
value = cv.ensure_list(TOUCHSCREENS_CONFIG)(config)
|
||||||
|
if value or CONF_TOUCHSCREEN not in CORE.loaded_integrations:
|
||||||
|
return value
|
||||||
|
return [TOUCHSCREENS_CONFIG(config)]
|
||||||
|
|
||||||
|
|
||||||
|
async def touchscreens_to_code(var, config):
|
||||||
|
for tconf in config.get(CONF_TOUCHSCREENS) or ():
|
||||||
|
lvgl_components_required.add(CONF_TOUCHSCREEN)
|
||||||
|
touchscreen = await cg.get_variable(tconf[CONF_TOUCHSCREEN_ID])
|
||||||
|
lpt = tconf[CONF_LONG_PRESS_TIME].total_milliseconds
|
||||||
|
lprt = tconf[CONF_LONG_PRESS_REPEAT_TIME].total_milliseconds
|
||||||
|
listener = cg.new_Pvariable(tconf[CONF_ID], lpt, lprt)
|
||||||
|
await cg.register_parented(listener, var)
|
||||||
|
lv.indev_drv_register(listener.get_drv())
|
||||||
|
cg.add(touchscreen.register_listener(listener))
|
|
@ -1,7 +1,22 @@
|
||||||
from esphome import codegen as cg
|
from esphome import codegen as cg
|
||||||
from esphome.core import ID
|
from esphome.core import ID
|
||||||
|
from esphome.cpp_generator import MockObjClass
|
||||||
|
|
||||||
|
from .defines import CONF_TEXT
|
||||||
|
|
||||||
|
|
||||||
|
class LvType(cg.MockObjClass):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
parens = kwargs.pop("parents", ())
|
||||||
|
super().__init__(*args, parents=parens + (lv_obj_base_t,))
|
||||||
|
self.args = kwargs.pop("largs", [(lv_obj_t_ptr, "obj")])
|
||||||
|
self.value = kwargs.pop("lvalue", lambda w: w.obj)
|
||||||
|
self.has_on_value = kwargs.pop("has_on_value", False)
|
||||||
|
self.value_property = None
|
||||||
|
|
||||||
|
def get_arg_type(self):
|
||||||
|
return self.args[0][0] if len(self.args) else None
|
||||||
|
|
||||||
from .defines import CONF_LABEL, CONF_OBJ, CONF_TEXT
|
|
||||||
|
|
||||||
uint16_t_ptr = cg.uint16.operator("ptr")
|
uint16_t_ptr = cg.uint16.operator("ptr")
|
||||||
lvgl_ns = cg.esphome_ns.namespace("lvgl")
|
lvgl_ns = cg.esphome_ns.namespace("lvgl")
|
||||||
|
@ -18,25 +33,15 @@ lv_obj_base_t = cg.global_ns.class_("lv_obj_t", lv_pseudo_button_t)
|
||||||
lv_obj_t_ptr = lv_obj_base_t.operator("ptr")
|
lv_obj_t_ptr = lv_obj_base_t.operator("ptr")
|
||||||
lv_disp_t_ptr = cg.global_ns.struct("lv_disp_t").operator("ptr")
|
lv_disp_t_ptr = cg.global_ns.struct("lv_disp_t").operator("ptr")
|
||||||
lv_color_t = cg.global_ns.struct("lv_color_t")
|
lv_color_t = cg.global_ns.struct("lv_color_t")
|
||||||
|
LVTouchListener = lvgl_ns.class_("LVTouchListener")
|
||||||
|
LVEncoderListener = lvgl_ns.class_("LVEncoderListener")
|
||||||
|
lv_obj_t = LvType("lv_obj_t")
|
||||||
|
|
||||||
|
|
||||||
# this will be populated later, in __init__.py to avoid circular imports.
|
# this will be populated later, in __init__.py to avoid circular imports.
|
||||||
WIDGET_TYPES: dict = {}
|
WIDGET_TYPES: dict = {}
|
||||||
|
|
||||||
|
|
||||||
class LvType(cg.MockObjClass):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
parens = kwargs.pop("parents", ())
|
|
||||||
super().__init__(*args, parents=parens + (lv_obj_base_t,))
|
|
||||||
self.args = kwargs.pop("largs", [(lv_obj_t_ptr, "obj")])
|
|
||||||
self.value = kwargs.pop("lvalue", lambda w: w.obj)
|
|
||||||
self.has_on_value = kwargs.pop("has_on_value", False)
|
|
||||||
self.value_property = None
|
|
||||||
|
|
||||||
def get_arg_type(self):
|
|
||||||
return self.args[0][0] if len(self.args) else None
|
|
||||||
|
|
||||||
|
|
||||||
class LvText(LvType):
|
class LvText(LvType):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
@ -48,17 +53,74 @@ class LvText(LvType):
|
||||||
self.value_property = CONF_TEXT
|
self.value_property = CONF_TEXT
|
||||||
|
|
||||||
|
|
||||||
lv_obj_t = LvType("lv_obj_t")
|
class LvBoolean(LvType):
|
||||||
lv_label_t = LvText("lv_label_t")
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(
|
||||||
LV_TYPES = {
|
*args,
|
||||||
CONF_LABEL: lv_label_t,
|
largs=[(cg.bool_, "x")],
|
||||||
CONF_OBJ: lv_obj_t,
|
lvalue=lambda w: w.is_checked(),
|
||||||
}
|
has_on_value=True,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
def get_widget_type(typestr: str) -> LvType:
|
|
||||||
return LV_TYPES[typestr]
|
|
||||||
|
|
||||||
|
|
||||||
CUSTOM_EVENT = ID("lv_custom_event", False, type=lv_event_code_t)
|
CUSTOM_EVENT = ID("lv_custom_event", False, type=lv_event_code_t)
|
||||||
|
|
||||||
|
|
||||||
|
class WidgetType:
|
||||||
|
"""
|
||||||
|
Describes a type of Widget, e.g. "bar" or "line"
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, w_type, parts, schema=None, modify_schema=None):
|
||||||
|
"""
|
||||||
|
:param name: The widget name, e.g. "bar"
|
||||||
|
:param w_type: The C type of the widget
|
||||||
|
:param parts: What parts this widget supports
|
||||||
|
:param schema: The config schema for defining a widget
|
||||||
|
:param modify_schema: A schema to update the widget
|
||||||
|
"""
|
||||||
|
self.name = name
|
||||||
|
self.w_type = w_type
|
||||||
|
self.parts = parts
|
||||||
|
self.schema = schema or {}
|
||||||
|
if modify_schema is None:
|
||||||
|
self.modify_schema = schema
|
||||||
|
else:
|
||||||
|
self.modify_schema = modify_schema
|
||||||
|
|
||||||
|
@property
|
||||||
|
def animated(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def required_component(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_compound(self):
|
||||||
|
return self.w_type.inherits_from(LvCompound)
|
||||||
|
|
||||||
|
async def to_code(self, w, config: dict):
|
||||||
|
"""
|
||||||
|
Generate code for a given widget
|
||||||
|
:param w: The widget
|
||||||
|
:param config: Its configuration
|
||||||
|
:return: Generated code as a list of text lines
|
||||||
|
"""
|
||||||
|
raise NotImplementedError(f"No to_code defined for {self.name}")
|
||||||
|
|
||||||
|
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||||
|
"""
|
||||||
|
Create an instance of the widget type
|
||||||
|
:param parent: The parent to which it should be attached
|
||||||
|
:param config: Its configuration
|
||||||
|
:return: Generated code as a single text line
|
||||||
|
"""
|
||||||
|
return f"lv_{self.name}_create({parent})"
|
||||||
|
|
||||||
|
def get_uses(self):
|
||||||
|
"""
|
||||||
|
Get a list of other widgets used by this one
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return ()
|
||||||
|
|
|
@ -21,78 +21,19 @@ from .defines import (
|
||||||
)
|
)
|
||||||
from .helpers import add_lv_use
|
from .helpers import add_lv_use
|
||||||
from .lvcode import ConstantLiteral, add_line_marks, lv, lv_add, lv_assign, lv_obj
|
from .lvcode import ConstantLiteral, add_line_marks, lv, lv_add, lv_assign, lv_obj
|
||||||
from .schemas import ALL_STYLES
|
from .schemas import ALL_STYLES, STYLE_REMAP
|
||||||
from .types import WIDGET_TYPES, LvCompound, lv_obj_t
|
from .types import WIDGET_TYPES, WidgetType, lv_obj_t
|
||||||
|
|
||||||
EVENT_LAMB = "event_lamb__"
|
EVENT_LAMB = "event_lamb__"
|
||||||
|
|
||||||
|
|
||||||
class WidgetType:
|
|
||||||
"""
|
|
||||||
Describes a type of Widget, e.g. "bar" or "line"
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name, schema=None, modify_schema=None):
|
|
||||||
"""
|
|
||||||
:param name: The widget name, e.g. "bar"
|
|
||||||
:param schema: The config schema for defining a widget
|
|
||||||
:param modify_schema: A schema to update the widget
|
|
||||||
"""
|
|
||||||
self.name = name
|
|
||||||
self.schema = schema or {}
|
|
||||||
if modify_schema is None:
|
|
||||||
self.modify_schema = schema
|
|
||||||
else:
|
|
||||||
self.modify_schema = modify_schema
|
|
||||||
|
|
||||||
@property
|
|
||||||
def animated(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def w_type(self):
|
|
||||||
"""
|
|
||||||
Get the type associated with this widget
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
return lv_obj_t
|
|
||||||
|
|
||||||
def is_compound(self):
|
|
||||||
return self.w_type.inherits_from(LvCompound)
|
|
||||||
|
|
||||||
async def to_code(self, w, config: dict):
|
|
||||||
"""
|
|
||||||
Generate code for a given widget
|
|
||||||
:param w: The widget
|
|
||||||
:param config: Its configuration
|
|
||||||
:return: Generated code as a list of text lines
|
|
||||||
"""
|
|
||||||
raise NotImplementedError(f"No to_code defined for {self.name}")
|
|
||||||
|
|
||||||
def obj_creator(self, parent: MockObjClass, config: dict):
|
|
||||||
"""
|
|
||||||
Create an instance of the widget type
|
|
||||||
:param parent: The parent to which it should be attached
|
|
||||||
:param config: Its configuration
|
|
||||||
:return: Generated code as a single text line
|
|
||||||
"""
|
|
||||||
return f"lv_{self.name}_create({parent})"
|
|
||||||
|
|
||||||
def get_uses(self):
|
|
||||||
"""
|
|
||||||
Get a list of other widgets used by this one
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
return ()
|
|
||||||
|
|
||||||
|
|
||||||
class LvScrActType(WidgetType):
|
class LvScrActType(WidgetType):
|
||||||
"""
|
"""
|
||||||
A "widget" representing the active screen.
|
A "widget" representing the active screen.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("lv_scr_act()")
|
super().__init__("lv_scr_act()", lv_obj_t, ())
|
||||||
|
|
||||||
def obj_creator(self, parent: MockObjClass, config: dict):
|
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||||
return []
|
return []
|
||||||
|
@ -263,7 +204,9 @@ async def set_obj_properties(w: Widget, config):
|
||||||
}.items():
|
}.items():
|
||||||
if isinstance(ALL_STYLES[prop], LValidator):
|
if isinstance(ALL_STYLES[prop], LValidator):
|
||||||
value = await ALL_STYLES[prop].process(value)
|
value = await ALL_STYLES[prop].process(value)
|
||||||
w.set_style(prop, value, lv_state)
|
# Remapping for backwards compatibility of style names
|
||||||
|
prop_r = STYLE_REMAP.get(prop, prop)
|
||||||
|
w.set_style(prop_r, value, lv_state)
|
||||||
flag_clr = set()
|
flag_clr = set()
|
||||||
flag_set = set()
|
flag_set = set()
|
||||||
props = parts[CONF_MAIN][CONF_DEFAULT]
|
props = parts[CONF_MAIN][CONF_DEFAULT]
|
||||||
|
@ -291,10 +234,10 @@ async def set_obj_properties(w: Widget, config):
|
||||||
else:
|
else:
|
||||||
clears.add(key)
|
clears.add(key)
|
||||||
if adds:
|
if adds:
|
||||||
adds = ConstantLiteral(join_enums(adds, "LV_STATE_"))
|
adds = join_enums(adds, "LV_STATE_")
|
||||||
w.add_state(adds)
|
w.add_state(adds)
|
||||||
if clears:
|
if clears:
|
||||||
clears = ConstantLiteral(join_enums(clears, "LV_STATE_"))
|
clears = join_enums(clears, "LV_STATE_")
|
||||||
w.clear_state(clears)
|
w.clear_state(clears)
|
||||||
for key, value in lambs.items():
|
for key, value in lambs.items():
|
||||||
lamb = await cg.process_lambda(value, [], return_type=cg.bool_)
|
lamb = await cg.process_lambda(value, [], return_type=cg.bool_)
|
||||||
|
|
|
@ -110,7 +110,7 @@ void MitsubishiClimate::transmit_state() {
|
||||||
// Byte 15: HVAC specfic, i.e. POWERFUL, SMART SET, PLASMA, always 0x00
|
// Byte 15: HVAC specfic, i.e. POWERFUL, SMART SET, PLASMA, always 0x00
|
||||||
// Byte 16: Constant 0x00
|
// Byte 16: Constant 0x00
|
||||||
// Byte 17: Checksum: SUM[Byte0...Byte16]
|
// Byte 17: Checksum: SUM[Byte0...Byte16]
|
||||||
uint8_t remote_state[18] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x00, 0x00,
|
uint8_t remote_state[18] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
switch (this->mode) {
|
switch (this->mode) {
|
||||||
|
@ -136,6 +136,12 @@ void MitsubishiClimate::transmit_state() {
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_MODE_OFF:
|
case climate::CLIMATE_MODE_OFF:
|
||||||
default:
|
default:
|
||||||
|
remote_state[6] = MITSUBISHI_MODE_COOL;
|
||||||
|
remote_state[8] = MITSUBISHI_MODE_A_COOL;
|
||||||
|
if (this->supports_heat_) {
|
||||||
|
remote_state[6] = MITSUBISHI_MODE_HEAT;
|
||||||
|
remote_state[8] = MITSUBISHI_MODE_A_HEAT;
|
||||||
|
}
|
||||||
remote_state[5] = MITSUBISHI_OFF;
|
remote_state[5] = MITSUBISHI_OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
|
from esphome import automation
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome import automation
|
from esphome.const import (
|
||||||
|
CONF_ESPHOME,
|
||||||
|
CONF_ON_ERROR,
|
||||||
|
CONF_OTA,
|
||||||
|
CONF_PLATFORM,
|
||||||
|
CONF_TRIGGER_ID,
|
||||||
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
|
|
||||||
from esphome.const import CONF_ESPHOME, CONF_OTA, CONF_PLATFORM, CONF_TRIGGER_ID
|
|
||||||
|
|
||||||
CODEOWNERS = ["@esphome/core"]
|
CODEOWNERS = ["@esphome/core"]
|
||||||
AUTO_LOAD = ["md5", "safe_mode"]
|
AUTO_LOAD = ["md5", "safe_mode"]
|
||||||
|
|
||||||
|
@ -13,7 +18,6 @@ IS_PLATFORM_COMPONENT = True
|
||||||
CONF_ON_ABORT = "on_abort"
|
CONF_ON_ABORT = "on_abort"
|
||||||
CONF_ON_BEGIN = "on_begin"
|
CONF_ON_BEGIN = "on_begin"
|
||||||
CONF_ON_END = "on_end"
|
CONF_ON_END = "on_end"
|
||||||
CONF_ON_ERROR = "on_error"
|
|
||||||
CONF_ON_PROGRESS = "on_progress"
|
CONF_ON_PROGRESS = "on_progress"
|
||||||
CONF_ON_STATE_CHANGE = "on_state_change"
|
CONF_ON_STATE_CHANGE = "on_state_change"
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,8 @@ class PIDClimate : public climate::Climate, public Component {
|
||||||
float get_kp() { return controller_.kp_; }
|
float get_kp() { return controller_.kp_; }
|
||||||
float get_ki() { return controller_.ki_; }
|
float get_ki() { return controller_.ki_; }
|
||||||
float get_kd() { return controller_.kd_; }
|
float get_kd() { return controller_.kd_; }
|
||||||
|
float get_min_integral() { return controller_.min_integral_; }
|
||||||
|
float get_max_integral() { return controller_.max_integral_; }
|
||||||
float get_proportional_term() const { return controller_.proportional_term_; }
|
float get_proportional_term() const { return controller_.proportional_term_; }
|
||||||
float get_integral_term() const { return controller_.integral_term_; }
|
float get_integral_term() const { return controller_.integral_term_; }
|
||||||
float get_derivative_term() const { return controller_.derivative_term_; }
|
float get_derivative_term() const { return controller_.derivative_term_; }
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
|
|
||||||
from esphome.components import binary_sensor, display
|
from esphome.components import binary_sensor, display
|
||||||
from esphome.const import CONF_PAGE_ID
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_PAGE_ID, CONF_PAGES
|
||||||
|
|
||||||
from .. import touchscreen_ns, CONF_TOUCHSCREEN_ID, Touchscreen, TouchListener
|
from .. import CONF_TOUCHSCREEN_ID, TouchListener, Touchscreen, touchscreen_ns
|
||||||
|
|
||||||
DEPENDENCIES = ["touchscreen"]
|
DEPENDENCIES = ["touchscreen"]
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ CONF_Y_MIN = "y_min"
|
||||||
CONF_Y_MAX = "y_max"
|
CONF_Y_MAX = "y_max"
|
||||||
|
|
||||||
|
|
||||||
def validate_coords(config):
|
def _validate_coords(config):
|
||||||
if (
|
if (
|
||||||
config[CONF_X_MAX] < config[CONF_X_MIN]
|
config[CONF_X_MAX] < config[CONF_X_MIN]
|
||||||
or config[CONF_Y_MAX] < config[CONF_Y_MIN]
|
or config[CONF_Y_MAX] < config[CONF_Y_MIN]
|
||||||
|
@ -33,6 +32,15 @@ def validate_coords(config):
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def _set_pages(config: dict) -> dict:
|
||||||
|
if CONF_PAGES in config or CONF_PAGE_ID not in config:
|
||||||
|
return config
|
||||||
|
|
||||||
|
config = config.copy()
|
||||||
|
config[CONF_PAGES] = [config.pop(CONF_PAGE_ID)]
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
binary_sensor.binary_sensor_schema(TouchscreenBinarySensor)
|
binary_sensor.binary_sensor_schema(TouchscreenBinarySensor)
|
||||||
.extend(
|
.extend(
|
||||||
|
@ -42,11 +50,17 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Required(CONF_X_MAX): cv.int_range(min=0, max=2000),
|
cv.Required(CONF_X_MAX): cv.int_range(min=0, max=2000),
|
||||||
cv.Required(CONF_Y_MIN): cv.int_range(min=0, max=2000),
|
cv.Required(CONF_Y_MIN): cv.int_range(min=0, max=2000),
|
||||||
cv.Required(CONF_Y_MAX): cv.int_range(min=0, max=2000),
|
cv.Required(CONF_Y_MAX): cv.int_range(min=0, max=2000),
|
||||||
cv.Optional(CONF_PAGE_ID): cv.use_id(display.DisplayPage),
|
cv.Exclusive(CONF_PAGE_ID, group_of_exclusion=CONF_PAGES): cv.use_id(
|
||||||
|
display.DisplayPage
|
||||||
|
),
|
||||||
|
cv.Exclusive(CONF_PAGES, group_of_exclusion=CONF_PAGES): cv.ensure_list(
|
||||||
|
cv.use_id(display.DisplayPage)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.COMPONENT_SCHEMA),
|
.extend(cv.COMPONENT_SCHEMA),
|
||||||
validate_coords,
|
_validate_coords,
|
||||||
|
_set_pages,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,6 +78,6 @@ async def to_code(config):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if CONF_PAGE_ID in config:
|
for page_id in config.get(CONF_PAGES, []):
|
||||||
page = await cg.get_variable(config[CONF_PAGE_ID])
|
page = await cg.get_variable(page_id)
|
||||||
cg.add(var.set_page(page))
|
cg.add(var.add_page(page))
|
||||||
|
|
|
@ -11,8 +11,9 @@ void TouchscreenBinarySensor::setup() {
|
||||||
void TouchscreenBinarySensor::touch(TouchPoint tp) {
|
void TouchscreenBinarySensor::touch(TouchPoint tp) {
|
||||||
bool touched = (tp.x >= this->x_min_ && tp.x <= this->x_max_ && tp.y >= this->y_min_ && tp.y <= this->y_max_);
|
bool touched = (tp.x >= this->x_min_ && tp.x <= this->x_max_ && tp.y >= this->y_min_ && tp.y <= this->y_max_);
|
||||||
|
|
||||||
if (this->page_ != nullptr) {
|
if (!this->pages_.empty()) {
|
||||||
touched &= this->page_ == this->parent_->get_display()->get_active_page();
|
auto *current_page = this->parent_->get_display()->get_active_page();
|
||||||
|
touched &= std::find(this->pages_.begin(), this->pages_.end(), current_page) != this->pages_.end();
|
||||||
}
|
}
|
||||||
if (touched) {
|
if (touched) {
|
||||||
this->publish_state(true);
|
this->publish_state(true);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace touchscreen {
|
namespace touchscreen {
|
||||||
|
|
||||||
|
@ -30,14 +32,14 @@ class TouchscreenBinarySensor : public binary_sensor::BinarySensor,
|
||||||
int16_t get_width() { return this->x_max_ - this->x_min_; }
|
int16_t get_width() { return this->x_max_ - this->x_min_; }
|
||||||
int16_t get_height() { return this->y_max_ - this->y_min_; }
|
int16_t get_height() { return this->y_max_ - this->y_min_; }
|
||||||
|
|
||||||
void set_page(display::DisplayPage *page) { this->page_ = page; }
|
void add_page(display::DisplayPage *page) { this->pages_.push_back(page); }
|
||||||
|
|
||||||
void touch(TouchPoint tp) override;
|
void touch(TouchPoint tp) override;
|
||||||
void release() override;
|
void release() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int16_t x_min_, x_max_, y_min_, y_max_;
|
int16_t x_min_, x_max_, y_min_, y_max_;
|
||||||
display::DisplayPage *page_{nullptr};
|
std::vector<display::DisplayPage *> pages_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace touchscreen
|
} // namespace touchscreen
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.codegen as cg
|
|
||||||
|
|
||||||
from esphome.const import (
|
|
||||||
CONF_ID,
|
|
||||||
CONF_MICROPHONE,
|
|
||||||
CONF_SPEAKER,
|
|
||||||
CONF_MEDIA_PLAYER,
|
|
||||||
CONF_ON_CLIENT_CONNECTED,
|
|
||||||
CONF_ON_CLIENT_DISCONNECTED,
|
|
||||||
CONF_ON_IDLE,
|
|
||||||
)
|
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
from esphome.automation import register_action, register_condition
|
from esphome.automation import register_action, register_condition
|
||||||
from esphome.components import microphone, speaker, media_player
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import media_player, microphone, speaker
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_ID,
|
||||||
|
CONF_MEDIA_PLAYER,
|
||||||
|
CONF_MICROPHONE,
|
||||||
|
CONF_ON_CLIENT_CONNECTED,
|
||||||
|
CONF_ON_CLIENT_DISCONNECTED,
|
||||||
|
CONF_ON_ERROR,
|
||||||
|
CONF_ON_IDLE,
|
||||||
|
CONF_SPEAKER,
|
||||||
|
)
|
||||||
|
|
||||||
AUTO_LOAD = ["socket"]
|
AUTO_LOAD = ["socket"]
|
||||||
DEPENDENCIES = ["api", "microphone"]
|
DEPENDENCIES = ["api", "microphone"]
|
||||||
|
@ -20,7 +20,6 @@ DEPENDENCIES = ["api", "microphone"]
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
|
||||||
CONF_ON_END = "on_end"
|
CONF_ON_END = "on_end"
|
||||||
CONF_ON_ERROR = "on_error"
|
|
||||||
CONF_ON_INTENT_END = "on_intent_end"
|
CONF_ON_INTENT_END = "on_intent_end"
|
||||||
CONF_ON_INTENT_START = "on_intent_start"
|
CONF_ON_INTENT_START = "on_intent_start"
|
||||||
CONF_ON_LISTENING = "on_listening"
|
CONF_ON_LISTENING = "on_listening"
|
||||||
|
|
1
esphome/components/watchdog/__init__.py
Normal file
1
esphome/components/watchdog/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ["@oarcher"]
|
|
@ -15,7 +15,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace http_request {
|
|
||||||
namespace watchdog {
|
namespace watchdog {
|
||||||
|
|
||||||
static const char *const TAG = "http_request.watchdog";
|
static const char *const TAG = "http_request.watchdog";
|
||||||
|
@ -72,5 +71,4 @@ uint32_t WatchdogManager::get_timeout_() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace watchdog
|
} // namespace watchdog
|
||||||
} // namespace http_request
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
|
@ -5,7 +5,6 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace http_request {
|
|
||||||
namespace watchdog {
|
namespace watchdog {
|
||||||
|
|
||||||
class WatchdogManager {
|
class WatchdogManager {
|
||||||
|
@ -22,5 +21,4 @@ class WatchdogManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace watchdog
|
} // namespace watchdog
|
||||||
} // namespace http_request
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
|
@ -1,15 +1,19 @@
|
||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.final_validate as fv
|
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
from esphome.automation import Condition
|
from esphome.automation import Condition
|
||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components.esp32 import add_idf_sdkconfig_option, const, get_esp32_variant
|
||||||
|
from esphome.components.network import IPAddress
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_AP,
|
CONF_AP,
|
||||||
CONF_BSSID,
|
CONF_BSSID,
|
||||||
|
CONF_CERTIFICATE,
|
||||||
|
CONF_CERTIFICATE_AUTHORITY,
|
||||||
CONF_CHANNEL,
|
CONF_CHANNEL,
|
||||||
CONF_DNS1,
|
CONF_DNS1,
|
||||||
CONF_DNS2,
|
CONF_DNS2,
|
||||||
CONF_DOMAIN,
|
CONF_DOMAIN,
|
||||||
|
CONF_EAP,
|
||||||
CONF_ENABLE_BTM,
|
CONF_ENABLE_BTM,
|
||||||
CONF_ENABLE_ON_BOOT,
|
CONF_ENABLE_ON_BOOT,
|
||||||
CONF_ENABLE_RRM,
|
CONF_ENABLE_RRM,
|
||||||
|
@ -17,29 +21,26 @@ from esphome.const import (
|
||||||
CONF_GATEWAY,
|
CONF_GATEWAY,
|
||||||
CONF_HIDDEN,
|
CONF_HIDDEN,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
CONF_IDENTITY,
|
||||||
|
CONF_KEY,
|
||||||
CONF_MANUAL_IP,
|
CONF_MANUAL_IP,
|
||||||
CONF_NETWORKS,
|
CONF_NETWORKS,
|
||||||
|
CONF_ON_CONNECT,
|
||||||
|
CONF_ON_DISCONNECT,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
CONF_POWER_SAVE_MODE,
|
CONF_POWER_SAVE_MODE,
|
||||||
|
CONF_PRIORITY,
|
||||||
CONF_REBOOT_TIMEOUT,
|
CONF_REBOOT_TIMEOUT,
|
||||||
CONF_SSID,
|
CONF_SSID,
|
||||||
CONF_STATIC_IP,
|
CONF_STATIC_IP,
|
||||||
CONF_SUBNET,
|
CONF_SUBNET,
|
||||||
CONF_USE_ADDRESS,
|
|
||||||
CONF_PRIORITY,
|
|
||||||
CONF_IDENTITY,
|
|
||||||
CONF_CERTIFICATE_AUTHORITY,
|
|
||||||
CONF_CERTIFICATE,
|
|
||||||
CONF_KEY,
|
|
||||||
CONF_USERNAME,
|
|
||||||
CONF_EAP,
|
|
||||||
CONF_TTLS_PHASE_2,
|
CONF_TTLS_PHASE_2,
|
||||||
CONF_ON_CONNECT,
|
CONF_USE_ADDRESS,
|
||||||
CONF_ON_DISCONNECT,
|
CONF_USERNAME,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, HexInt, coroutine_with_priority
|
from esphome.core import CORE, HexInt, coroutine_with_priority
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant, const
|
import esphome.final_validate as fv
|
||||||
from esphome.components.network import IPAddress
|
|
||||||
from . import wpa2_eap
|
from . import wpa2_eap
|
||||||
|
|
||||||
AUTO_LOAD = ["network"]
|
AUTO_LOAD = ["network"]
|
||||||
|
|
|
@ -7,16 +7,15 @@ so that it doesn't crash if it's not installed.
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from esphome.core import CORE
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_USERNAME,
|
|
||||||
CONF_IDENTITY,
|
|
||||||
CONF_PASSWORD,
|
|
||||||
CONF_CERTIFICATE,
|
CONF_CERTIFICATE,
|
||||||
|
CONF_IDENTITY,
|
||||||
CONF_KEY,
|
CONF_KEY,
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_USERNAME,
|
||||||
)
|
)
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -49,8 +48,8 @@ def wrapped_load_pem_x509_certificate(value):
|
||||||
def wrapped_load_pem_private_key(value, password):
|
def wrapped_load_pem_private_key(value, password):
|
||||||
validate_cryptography_installed()
|
validate_cryptography_installed()
|
||||||
|
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
|
|
||||||
if password:
|
if password:
|
||||||
password = password.encode("UTF-8")
|
password = password.encode("UTF-8")
|
||||||
|
@ -91,7 +90,7 @@ def _validate_load_private_key(key, cert_pw):
|
||||||
|
|
||||||
|
|
||||||
def _check_private_key_cert_match(key, cert):
|
def _check_private_key_cert_match(key, cert):
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa, ec
|
from cryptography.hazmat.primitives.asymmetric import ec, rsa
|
||||||
|
|
||||||
def check_match_a():
|
def check_match_a():
|
||||||
return key.public_key().public_numbers() == cert.public_key().public_numbers()
|
return key.public_key().public_numbers() == cert.public_key().public_numbers()
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components import text_sensor
|
from esphome.components import text_sensor
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_BSSID,
|
CONF_BSSID,
|
||||||
|
CONF_DNS_ADDRESS,
|
||||||
CONF_IP_ADDRESS,
|
CONF_IP_ADDRESS,
|
||||||
|
CONF_MAC_ADDRESS,
|
||||||
CONF_SCAN_RESULTS,
|
CONF_SCAN_RESULTS,
|
||||||
CONF_SSID,
|
CONF_SSID,
|
||||||
CONF_MAC_ADDRESS,
|
|
||||||
CONF_DNS_ADDRESS,
|
|
||||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components import sensor
|
from esphome.components import sensor
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
|
|
@ -1,40 +1,38 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
from contextlib import contextmanager
|
||||||
|
import contextvars
|
||||||
import functools
|
import functools
|
||||||
import heapq
|
import heapq
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from typing import Any, Union
|
||||||
from typing import Union, Any
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
|
||||||
import contextvars
|
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from esphome import core, yaml_util, loader, pins
|
from esphome import core, loader, pins, yaml_util
|
||||||
import esphome.core.config as core_config
|
from esphome.config_helpers import Extend, Remove
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ESPHOME,
|
CONF_ESPHOME,
|
||||||
CONF_ID,
|
|
||||||
CONF_PLATFORM,
|
|
||||||
CONF_PACKAGES,
|
|
||||||
CONF_SUBSTITUTIONS,
|
|
||||||
CONF_EXTERNAL_COMPONENTS,
|
CONF_EXTERNAL_COMPONENTS,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_PACKAGES,
|
||||||
|
CONF_PLATFORM,
|
||||||
|
CONF_SUBSTITUTIONS,
|
||||||
TARGET_PLATFORMS,
|
TARGET_PLATFORMS,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, EsphomeError, DocumentRange
|
from esphome.core import CORE, DocumentRange, EsphomeError
|
||||||
from esphome.helpers import indent
|
import esphome.core.config as core_config
|
||||||
from esphome.util import safe_print, OrderedDict
|
|
||||||
|
|
||||||
from esphome.config_helpers import Extend, Remove
|
|
||||||
from esphome.loader import get_component, get_platform, ComponentManifest
|
|
||||||
from esphome.yaml_util import is_secret, ESPHomeDataBase, ESPForceValue
|
|
||||||
from esphome.voluptuous_schema import ExtraKeysInvalid
|
|
||||||
from esphome.log import color, Fore
|
|
||||||
import esphome.final_validate as fv
|
import esphome.final_validate as fv
|
||||||
import esphome.config_validation as cv
|
from esphome.helpers import indent
|
||||||
from esphome.types import ConfigType, ConfigFragmentType
|
from esphome.loader import ComponentManifest, get_component, get_platform
|
||||||
|
from esphome.log import Fore, color
|
||||||
|
from esphome.types import ConfigFragmentType, ConfigType
|
||||||
|
from esphome.util import OrderedDict, safe_print
|
||||||
|
from esphome.voluptuous_schema import ExtraKeysInvalid
|
||||||
|
from esphome.yaml_util import ESPForceValue, ESPHomeDataBase, is_secret
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
"""Helpers for config validation using voluptuous."""
|
"""Helpers for config validation using voluptuous."""
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from contextlib import contextmanager
|
|
||||||
import uuid as uuid_
|
|
||||||
from datetime import datetime
|
|
||||||
from string import ascii_letters, digits
|
from string import ascii_letters, digits
|
||||||
|
import uuid as uuid_
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
@ -17,37 +17,37 @@ from esphome.config_helpers import Extend, Remove
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
ALLOWED_NAME_CHARS,
|
ALLOWED_NAME_CHARS,
|
||||||
CONF_AVAILABILITY,
|
CONF_AVAILABILITY,
|
||||||
CONF_COMMAND_TOPIC,
|
|
||||||
CONF_COMMAND_RETAIN,
|
CONF_COMMAND_RETAIN,
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_DAY,
|
||||||
CONF_DISABLED_BY_DEFAULT,
|
CONF_DISABLED_BY_DEFAULT,
|
||||||
CONF_DISCOVERY,
|
CONF_DISCOVERY,
|
||||||
CONF_ENTITY_CATEGORY,
|
CONF_ENTITY_CATEGORY,
|
||||||
|
CONF_HOUR,
|
||||||
CONF_ICON,
|
CONF_ICON,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_INTERNAL,
|
CONF_INTERNAL,
|
||||||
|
CONF_MINUTE,
|
||||||
|
CONF_MONTH,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_PATH,
|
||||||
CONF_PAYLOAD_AVAILABLE,
|
CONF_PAYLOAD_AVAILABLE,
|
||||||
CONF_PAYLOAD_NOT_AVAILABLE,
|
CONF_PAYLOAD_NOT_AVAILABLE,
|
||||||
CONF_RETAIN,
|
|
||||||
CONF_QOS,
|
CONF_QOS,
|
||||||
|
CONF_REF,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_SECOND,
|
||||||
CONF_SETUP_PRIORITY,
|
CONF_SETUP_PRIORITY,
|
||||||
CONF_STATE_TOPIC,
|
CONF_STATE_TOPIC,
|
||||||
CONF_TOPIC,
|
CONF_TOPIC,
|
||||||
CONF_YEAR,
|
|
||||||
CONF_MONTH,
|
|
||||||
CONF_DAY,
|
|
||||||
CONF_HOUR,
|
|
||||||
CONF_MINUTE,
|
|
||||||
CONF_SECOND,
|
|
||||||
CONF_VALUE,
|
|
||||||
CONF_UPDATE_INTERVAL,
|
|
||||||
CONF_TYPE_ID,
|
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
CONF_REF,
|
CONF_TYPE_ID,
|
||||||
|
CONF_UPDATE_INTERVAL,
|
||||||
CONF_URL,
|
CONF_URL,
|
||||||
CONF_PATH,
|
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
CONF_PASSWORD,
|
CONF_VALUE,
|
||||||
|
CONF_YEAR,
|
||||||
ENTITY_CATEGORY_CONFIG,
|
ENTITY_CATEGORY_CONFIG,
|
||||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
ENTITY_CATEGORY_NONE,
|
ENTITY_CATEGORY_NONE,
|
||||||
|
@ -71,15 +71,15 @@ from esphome.core import (
|
||||||
TimePeriod,
|
TimePeriod,
|
||||||
TimePeriodMicroseconds,
|
TimePeriodMicroseconds,
|
||||||
TimePeriodMilliseconds,
|
TimePeriodMilliseconds,
|
||||||
|
TimePeriodMinutes,
|
||||||
TimePeriodNanoseconds,
|
TimePeriodNanoseconds,
|
||||||
TimePeriodSeconds,
|
TimePeriodSeconds,
|
||||||
TimePeriodMinutes,
|
|
||||||
)
|
)
|
||||||
from esphome.helpers import list_starts_with, add_class_to_obj
|
from esphome.helpers import add_class_to_obj, list_starts_with
|
||||||
from esphome.schema_extractors import (
|
from esphome.schema_extractors import (
|
||||||
SCHEMA_EXTRACT,
|
SCHEMA_EXTRACT,
|
||||||
schema_extractor_list,
|
|
||||||
schema_extractor,
|
schema_extractor,
|
||||||
|
schema_extractor_list,
|
||||||
schema_extractor_registry,
|
schema_extractor_registry,
|
||||||
schema_extractor_typed,
|
schema_extractor_typed,
|
||||||
)
|
)
|
||||||
|
@ -1686,9 +1686,9 @@ class SplitDefault(Optional):
|
||||||
if CORE.is_esp32:
|
if CORE.is_esp32:
|
||||||
from esphome.components.esp32 import get_esp32_variant
|
from esphome.components.esp32 import get_esp32_variant
|
||||||
from esphome.components.esp32.const import (
|
from esphome.components.esp32.const import (
|
||||||
|
VARIANT_ESP32C3,
|
||||||
VARIANT_ESP32S2,
|
VARIANT_ESP32S2,
|
||||||
VARIANT_ESP32S3,
|
VARIANT_ESP32S3,
|
||||||
VARIANT_ESP32C3,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
variant = get_esp32_variant()
|
variant = get_esp32_variant()
|
||||||
|
|
|
@ -539,6 +539,7 @@ CONF_ON_DOUBLE_CLICK = "on_double_click"
|
||||||
CONF_ON_ENROLLMENT_DONE = "on_enrollment_done"
|
CONF_ON_ENROLLMENT_DONE = "on_enrollment_done"
|
||||||
CONF_ON_ENROLLMENT_FAILED = "on_enrollment_failed"
|
CONF_ON_ENROLLMENT_FAILED = "on_enrollment_failed"
|
||||||
CONF_ON_ENROLLMENT_SCAN = "on_enrollment_scan"
|
CONF_ON_ENROLLMENT_SCAN = "on_enrollment_scan"
|
||||||
|
CONF_ON_ERROR = "on_error"
|
||||||
CONF_ON_EVENT = "on_event"
|
CONF_ON_EVENT = "on_event"
|
||||||
CONF_ON_FINGER_SCAN_INVALID = "on_finger_scan_invalid"
|
CONF_ON_FINGER_SCAN_INVALID = "on_finger_scan_invalid"
|
||||||
CONF_ON_FINGER_SCAN_MATCHED = "on_finger_scan_matched"
|
CONF_ON_FINGER_SCAN_MATCHED = "on_finger_scan_matched"
|
||||||
|
@ -1032,11 +1033,13 @@ UNIT_KILOWATT_HOURS = "kWh"
|
||||||
UNIT_LUX = "lx"
|
UNIT_LUX = "lx"
|
||||||
UNIT_METER = "m"
|
UNIT_METER = "m"
|
||||||
UNIT_METER_PER_SECOND_SQUARED = "m/s²"
|
UNIT_METER_PER_SECOND_SQUARED = "m/s²"
|
||||||
|
UNIT_MICROAMP = "µA"
|
||||||
UNIT_MICROGRAMS_PER_CUBIC_METER = "µg/m³"
|
UNIT_MICROGRAMS_PER_CUBIC_METER = "µg/m³"
|
||||||
UNIT_MICROMETER = "µm"
|
UNIT_MICROMETER = "µm"
|
||||||
UNIT_MICROSIEMENS_PER_CENTIMETER = "µS/cm"
|
UNIT_MICROSIEMENS_PER_CENTIMETER = "µS/cm"
|
||||||
UNIT_MICROSILVERTS_PER_HOUR = "µSv/h"
|
UNIT_MICROSILVERTS_PER_HOUR = "µSv/h"
|
||||||
UNIT_MICROTESLA = "µT"
|
UNIT_MICROTESLA = "µT"
|
||||||
|
UNIT_MILLIAMP = "mA"
|
||||||
UNIT_MILLIGRAMS_PER_CUBIC_METER = "mg/m³"
|
UNIT_MILLIGRAMS_PER_CUBIC_METER = "mg/m³"
|
||||||
UNIT_MILLIMETER = "mm"
|
UNIT_MILLIMETER = "mm"
|
||||||
UNIT_MILLISECOND = "ms"
|
UNIT_MILLISECOND = "ms"
|
||||||
|
|
|
@ -7,26 +7,29 @@ from typing import TYPE_CHECKING, Optional, Union
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_COMMENT,
|
CONF_COMMENT,
|
||||||
CONF_ESPHOME,
|
CONF_ESPHOME,
|
||||||
CONF_USE_ADDRESS,
|
|
||||||
CONF_ETHERNET,
|
CONF_ETHERNET,
|
||||||
|
CONF_PORT,
|
||||||
|
CONF_USE_ADDRESS,
|
||||||
CONF_WEB_SERVER,
|
CONF_WEB_SERVER,
|
||||||
CONF_WIFI,
|
CONF_WIFI,
|
||||||
CONF_PORT,
|
|
||||||
KEY_CORE,
|
KEY_CORE,
|
||||||
KEY_TARGET_FRAMEWORK,
|
KEY_TARGET_FRAMEWORK,
|
||||||
KEY_TARGET_PLATFORM,
|
KEY_TARGET_PLATFORM,
|
||||||
|
PLATFORM_BK72XX,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
PLATFORM_BK72XX,
|
|
||||||
PLATFORM_RTL87XX,
|
|
||||||
PLATFORM_RP2040,
|
|
||||||
PLATFORM_HOST,
|
PLATFORM_HOST,
|
||||||
|
PLATFORM_RP2040,
|
||||||
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
from esphome.coroutine import FakeAwaitable as _FakeAwaitable
|
|
||||||
from esphome.coroutine import FakeEventLoop as _FakeEventLoop
|
|
||||||
|
|
||||||
# pylint: disable=unused-import
|
# pylint: disable=unused-import
|
||||||
from esphome.coroutine import coroutine, coroutine_with_priority # noqa
|
from esphome.coroutine import ( # noqa: F401
|
||||||
|
FakeAwaitable as _FakeAwaitable,
|
||||||
|
FakeEventLoop as _FakeEventLoop,
|
||||||
|
coroutine,
|
||||||
|
coroutine_with_priority,
|
||||||
|
)
|
||||||
from esphome.helpers import ensure_unique_string, get_str_env, is_ha_addon
|
from esphome.helpers import ensure_unique_string, get_str_env, is_ha_addon
|
||||||
from esphome.util import OrderedDict
|
from esphome.util import OrderedDict
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ import multiprocessing
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from esphome import automation
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome import automation
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ARDUINO_VERSION,
|
CONF_ARDUINO_VERSION,
|
||||||
CONF_AREA,
|
CONF_AREA,
|
||||||
|
@ -16,11 +16,11 @@ from esphome.const import (
|
||||||
CONF_COMPILE_PROCESS_LIMIT,
|
CONF_COMPILE_PROCESS_LIMIT,
|
||||||
CONF_ESPHOME,
|
CONF_ESPHOME,
|
||||||
CONF_FRAMEWORK,
|
CONF_FRAMEWORK,
|
||||||
|
CONF_FRIENDLY_NAME,
|
||||||
CONF_INCLUDES,
|
CONF_INCLUDES,
|
||||||
CONF_LIBRARIES,
|
CONF_LIBRARIES,
|
||||||
CONF_MIN_VERSION,
|
CONF_MIN_VERSION,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_FRIENDLY_NAME,
|
|
||||||
CONF_ON_BOOT,
|
CONF_ON_BOOT,
|
||||||
CONF_ON_LOOP,
|
CONF_ON_LOOP,
|
||||||
CONF_ON_SHUTDOWN,
|
CONF_ON_SHUTDOWN,
|
||||||
|
@ -34,8 +34,8 @@ from esphome.const import (
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
CONF_VERSION,
|
CONF_VERSION,
|
||||||
KEY_CORE,
|
KEY_CORE,
|
||||||
TARGET_PLATFORMS,
|
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
|
TARGET_PLATFORMS,
|
||||||
__version__ as ESPHOME_VERSION,
|
__version__ as ESPHOME_VERSION,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#define USE_LVGL
|
#define USE_LVGL
|
||||||
#define USE_LVGL_FONT
|
#define USE_LVGL_FONT
|
||||||
#define USE_LVGL_IMAGE
|
#define USE_LVGL_IMAGE
|
||||||
|
#define USE_LVGL_TOUCHSCREEN
|
||||||
#define USE_MDNS
|
#define USE_MDNS
|
||||||
#define USE_MEDIA_PLAYER
|
#define USE_MEDIA_PLAYER
|
||||||
#define USE_MQTT
|
#define USE_MQTT
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import esphome.final_validate as fv
|
|
||||||
|
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_ID
|
||||||
|
import esphome.final_validate as fv
|
||||||
|
|
||||||
|
|
||||||
def inherit_property_from(property_to_inherit, parent_id_property, transform=None):
|
def inherit_property_from(property_to_inherit, parent_id_property, transform=None):
|
||||||
|
|
|
@ -43,13 +43,13 @@ the last `yield` expression defines what is returned.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
from collections.abc import Awaitable, Generator, Iterator
|
||||||
import functools
|
import functools
|
||||||
import heapq
|
import heapq
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import types
|
import types
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
from collections.abc import Awaitable, Generator, Iterator
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import abc
|
import abc
|
||||||
|
from collections.abc import Sequence
|
||||||
import inspect
|
import inspect
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
from collections.abc import Sequence
|
|
||||||
from typing import Any, Callable, Optional, Union
|
from typing import Any, Callable, Optional, Union
|
||||||
|
|
||||||
from esphome.core import (
|
from esphome.core import (
|
||||||
|
|
|
@ -12,15 +12,13 @@ from esphome.const import (
|
||||||
CONF_UPDATE_INTERVAL,
|
CONF_UPDATE_INTERVAL,
|
||||||
KEY_PAST_SAFE_MODE,
|
KEY_PAST_SAFE_MODE,
|
||||||
)
|
)
|
||||||
|
from esphome.core import CORE, ID, coroutine
|
||||||
from esphome.core import coroutine, ID, CORE
|
|
||||||
from esphome.coroutine import FakeAwaitable
|
from esphome.coroutine import FakeAwaitable
|
||||||
from esphome.types import ConfigType, ConfigFragmentType
|
|
||||||
from esphome.cpp_generator import add, get_variable
|
from esphome.cpp_generator import add, get_variable
|
||||||
from esphome.cpp_types import App
|
from esphome.cpp_types import App
|
||||||
|
from esphome.helpers import sanitize, snake_case
|
||||||
|
from esphome.types import ConfigFragmentType, ConfigType
|
||||||
from esphome.util import Registry, RegistryEntry
|
from esphome.util import Registry, RegistryEntry
|
||||||
from esphome.helpers import snake_case, sanitize
|
|
||||||
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections.abc import Coroutine
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
|
||||||
import threading
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
from typing import TYPE_CHECKING, Any, Callable
|
from typing import TYPE_CHECKING, Any, Callable
|
||||||
from collections.abc import Coroutine
|
|
||||||
|
|
||||||
from ..zeroconf import DiscoveredImport
|
from ..zeroconf import DiscoveredImport
|
||||||
from .dns import DNSCache
|
from .dns import DNSCache
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from asyncio import events
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
|
||||||
from asyncio import events
|
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
|
||||||
from time import monotonic
|
from time import monotonic
|
||||||
|
import traceback
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from esphome.storage_json import EsphomeStorageJSON, esphome_storage_path
|
from esphome.storage_json import EsphomeStorageJSON, esphome_storage_path
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections import defaultdict
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from collections import defaultdict
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from esphome import const, util
|
from esphome import const, util
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import tempfile
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import tempfile
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import base64
|
import base64
|
||||||
|
from collections.abc import Iterable
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
import gzip
|
import gzip
|
||||||
|
@ -9,13 +10,12 @@ import hashlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
import secrets
|
import secrets
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from collections.abc import Iterable
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import TYPE_CHECKING, Any, Callable, TypeVar
|
from typing import TYPE_CHECKING, Any, Callable, TypeVar
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@ import tornado.httpserver
|
||||||
import tornado.httputil
|
import tornado.httputil
|
||||||
import tornado.ioloop
|
import tornado.ioloop
|
||||||
import tornado.iostream
|
import tornado.iostream
|
||||||
|
from tornado.log import access_log
|
||||||
import tornado.netutil
|
import tornado.netutil
|
||||||
import tornado.process
|
import tornado.process
|
||||||
import tornado.queues
|
import tornado.queues
|
||||||
import tornado.web
|
import tornado.web
|
||||||
import tornado.websocket
|
import tornado.websocket
|
||||||
import yaml
|
import yaml
|
||||||
from tornado.log import access_log
|
|
||||||
from yaml.nodes import Node
|
from yaml.nodes import Node
|
||||||
|
|
||||||
from esphome import const, platformio_api, yaml_util
|
from esphome import const, platformio_api, yaml_util
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
|
||||||
from pathlib import Path
|
|
||||||
import os
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.core import CORE, TimePeriodSeconds
|
|
||||||
from esphome.const import __version__
|
from esphome.const import __version__
|
||||||
|
from esphome.core import CORE, TimePeriodSeconds
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
CODEOWNERS = ["@landonr"]
|
CODEOWNERS = ["@landonr"]
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Any
|
|
||||||
import contextvars
|
import contextvars
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from esphome.types import ConfigFragmentType, ID, ConfigPathType
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.types import ID, ConfigFragmentType, ConfigPathType
|
||||||
|
|
||||||
|
|
||||||
class FinalValidateConfig(ABC):
|
class FinalValidateConfig(ABC):
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import hashlib
|
|
||||||
import logging
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import urllib.parse
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import hashlib
|
||||||
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
from typing import Callable, Optional
|
from typing import Callable, Optional
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.core import CORE, TimePeriodSeconds
|
from esphome.core import CORE, TimePeriodSeconds
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import codecs
|
import codecs
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
import platform
|
||||||
import tempfile
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
import re
|
import re
|
||||||
|
import tempfile
|
||||||
|
from typing import Union
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -129,9 +128,10 @@ def _resolve_with_zeroconf(host):
|
||||||
|
|
||||||
|
|
||||||
def resolve_ip_address(host):
|
def resolve_ip_address(host):
|
||||||
from esphome.core import EsphomeError
|
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
from esphome.core import EsphomeError
|
||||||
|
|
||||||
errs = []
|
errs = []
|
||||||
|
|
||||||
if host.endswith(".local"):
|
if host.endswith(".local"):
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import json
|
|
||||||
|
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ from esphome.const import (
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, EsphomeError
|
from esphome.core import CORE, EsphomeError
|
||||||
from esphome.log import color, Fore
|
from esphome.helpers import get_int_env, get_str_env
|
||||||
|
from esphome.log import Fore, color
|
||||||
from esphome.util import safe_print
|
from esphome.util import safe_print
|
||||||
from esphome.helpers import get_str_env, get_int_env
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
import operator
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
import esphome.config_validation as cv
|
import operator
|
||||||
from esphome.core import CORE
|
|
||||||
|
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
|
CONF_ALLOW_OTHER_USES,
|
||||||
|
CONF_IGNORE_STRAPPING_WARNING,
|
||||||
CONF_INPUT,
|
CONF_INPUT,
|
||||||
|
CONF_INVERTED,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
CONF_NUMBER,
|
CONF_NUMBER,
|
||||||
CONF_OPEN_DRAIN,
|
CONF_OPEN_DRAIN,
|
||||||
CONF_OUTPUT,
|
CONF_OUTPUT,
|
||||||
CONF_PULLDOWN,
|
CONF_PULLDOWN,
|
||||||
CONF_PULLUP,
|
CONF_PULLUP,
|
||||||
CONF_IGNORE_STRAPPING_WARNING,
|
|
||||||
CONF_ALLOW_OTHER_USES,
|
|
||||||
CONF_INVERTED,
|
|
||||||
)
|
)
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
|
|
||||||
class PinRegistry(dict):
|
class PinRegistry(dict):
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import json
|
import json
|
||||||
from typing import Union
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from esphome.const import CONF_COMPILE_PROCESS_LIMIT, CONF_ESPHOME, KEY_CORE
|
from esphome.const import CONF_COMPILE_PROCESS_LIMIT, CONF_ESPHOME, KEY_CORE
|
||||||
from esphome.core import CORE, EsphomeError
|
from esphome.core import CORE, EsphomeError
|
||||||
|
@ -20,9 +19,10 @@ def patch_structhash():
|
||||||
# removed/added. This might have unintended consequences, but this improves compile
|
# removed/added. This might have unintended consequences, but this improves compile
|
||||||
# times greatly when adding/removing components and a simple clean build solves
|
# times greatly when adding/removing components and a simple clean build solves
|
||||||
# all issues
|
# all issues
|
||||||
from platformio.run import helpers, cli
|
|
||||||
from os.path import join, isdir, getmtime
|
|
||||||
from os import makedirs
|
from os import makedirs
|
||||||
|
from os.path import getmtime, isdir, join
|
||||||
|
|
||||||
|
from platformio.run import cli, helpers
|
||||||
|
|
||||||
def patched_clean_build_dir(build_dir, *args):
|
def patched_clean_build_dir(build_dir, *args):
|
||||||
from platformio import fs
|
from platformio import fs
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
import codecs
|
import codecs
|
||||||
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from esphome import const
|
from esphome import const
|
||||||
from esphome.const import CONF_DISABLED, CONF_MDNS
|
from esphome.const import CONF_DISABLED, CONF_MDNS
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from esphome.core import ID, Lambda, EsphomeCore
|
from esphome.core import ID, EsphomeCore, Lambda
|
||||||
|
|
||||||
ConfigFragmentType = Union[
|
ConfigFragmentType = Union[
|
||||||
str,
|
str,
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from typing import Union
|
||||||
|
|
||||||
from esphome import const
|
from esphome import const
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import difflib
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from esphome.schema_extractors import schema_extractor_extended
|
from esphome.schema_extractors import schema_extractor_extended
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from io import StringIO
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from io import StringIO
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from esphome.yaml_util import parse_yaml
|
from esphome.config import Config, _format_vol_invalid, validate_config
|
||||||
from esphome.config import validate_config, _format_vol_invalid, Config
|
|
||||||
from esphome.core import CORE, DocumentRange
|
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.core import CORE, DocumentRange
|
||||||
|
from esphome.yaml_util import parse_yaml
|
||||||
|
|
||||||
|
|
||||||
def _get_invalid_range(res: Config, invalid: cv.Invalid) -> DocumentRange | None:
|
def _get_invalid_range(res: Config, invalid: cv.Invalid) -> DocumentRange | None:
|
||||||
|
|
|
@ -276,8 +276,8 @@ def wizard(path):
|
||||||
from esphome.components.bk72xx import boards as bk72xx_boards
|
from esphome.components.bk72xx import boards as bk72xx_boards
|
||||||
from esphome.components.esp32 import boards as esp32_boards
|
from esphome.components.esp32 import boards as esp32_boards
|
||||||
from esphome.components.esp8266 import boards as esp8266_boards
|
from esphome.components.esp8266 import boards as esp8266_boards
|
||||||
from esphome.components.rtl87xx import boards as rtl87xx_boards
|
|
||||||
from esphome.components.rp2040 import boards as rp2040_boards
|
from esphome.components.rp2040 import boards as rp2040_boards
|
||||||
|
from esphome.components.rtl87xx import boards as rtl87xx_boards
|
||||||
|
|
||||||
if not path.endswith(".yaml") and not path.endswith(".yml"):
|
if not path.endswith(".yaml") and not path.endswith(".yml"):
|
||||||
safe_print(
|
safe_print(
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import re
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from esphome.config import iter_components, iter_component_configs
|
from esphome import loader
|
||||||
|
from esphome.config import iter_component_configs, iter_components
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
|
ENV_NOGITIGNORE,
|
||||||
HEADER_FILE_EXTENSIONS,
|
HEADER_FILE_EXTENSIONS,
|
||||||
SOURCE_FILE_EXTENSIONS,
|
SOURCE_FILE_EXTENSIONS,
|
||||||
__version__,
|
__version__,
|
||||||
ENV_NOGITIGNORE,
|
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, EsphomeError
|
from esphome.core import CORE, EsphomeError
|
||||||
from esphome.helpers import (
|
from esphome.helpers import (
|
||||||
mkdir_p,
|
|
||||||
read_file,
|
|
||||||
write_file_if_changed,
|
|
||||||
walk_files,
|
|
||||||
copy_file_if_changed,
|
copy_file_if_changed,
|
||||||
get_bool_env,
|
get_bool_env,
|
||||||
|
mkdir_p,
|
||||||
|
read_file,
|
||||||
|
walk_files,
|
||||||
|
write_file_if_changed,
|
||||||
)
|
)
|
||||||
from esphome.storage_json import StorageJSON, storage_path
|
from esphome.storage_json import StorageJSON, storage_path
|
||||||
from esphome import loader
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,16 @@ from __future__ import annotations
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
|
from io import TextIOWrapper
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import uuid
|
|
||||||
from io import TextIOWrapper
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
import uuid
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
import yaml.constructor
|
|
||||||
from yaml import SafeLoader as PurePythonLoader
|
from yaml import SafeLoader as PurePythonLoader
|
||||||
|
import yaml.constructor
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from yaml import CSafeLoader as FastestAvailableSafeLoader
|
from yaml import CSafeLoader as FastestAvailableSafeLoader
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
import logging
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from zeroconf import IPVersion, ServiceInfo, ServiceStateChange, Zeroconf
|
from zeroconf import IPVersion, ServiceInfo, ServiceStateChange, Zeroconf
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
touchscreen:
|
||||||
|
- platform: ft63x6
|
||||||
|
id: tft_touch
|
||||||
|
display: tft_display
|
||||||
|
update_interval: 50ms
|
||||||
|
threshold: 1
|
||||||
|
calibration:
|
||||||
|
x_max: 240
|
||||||
|
y_max: 320
|
||||||
|
|
25
tests/components/lvgl/logo-text.svg
Normal file
25
tests/components/lvgl/logo-text.svg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 596.64 116.88">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
fill: #1d2126;
|
||||||
|
stroke-width: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="Layer_1-2" data-name="Layer 1">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="cls-1" d="M211.37,84.7v11.25h-43.5V25.87h43.5v11.34h-31.59v18.14h28.22v10.55h-28.22v18.8h31.59Z"/>
|
||||||
|
<path class="cls-1" d="M245.41,24.6c6.41,0,11.73,1.56,15.98,4.69,4.25,3.12,6.86,7.3,7.83,12.52l-11.2,3.05c-.63-3-2.09-5.31-4.38-6.94-2.3-1.62-5.13-2.44-8.51-2.44-3.63,0-6.5.87-8.62,2.6-2.13,1.73-3.19,4.04-3.19,6.91,0,4.53,2.81,7.47,8.44,8.81l11.44,2.86c5.91,1.53,10.33,3.96,13.27,7.29,2.94,3.33,4.41,7.43,4.41,12.3,0,6.25-2.27,11.3-6.8,15.16-4.53,3.86-10.59,5.79-18.19,5.79-6.84,0-12.63-1.61-17.34-4.83-4.66-3.34-7.41-7.75-8.25-13.22l11.2-2.91c.41,3.09,1.95,5.52,4.62,7.27,2.67,1.75,6.07,2.62,10.2,2.62s7.09-.84,9.35-2.51c2.27-1.67,3.4-3.94,3.4-6.82,0-4.5-2.81-7.47-8.44-8.91l-11.44-2.77c-5.88-1.34-10.29-3.73-13.24-7.15s-4.43-7.6-4.43-12.54c0-6.19,2.2-11.21,6.59-15.07,4.39-3.86,10.16-5.79,17.32-5.79Z"/>
|
||||||
|
<path class="cls-1" d="M332.92,48.7c0,6.88-2.09,12.44-6.26,16.69-4.17,4.25-9.79,6.38-16.85,6.38h-15.75v24.19h-11.91V25.87h27.75c7.12,0,12.74,2.06,16.85,6.16,4.11,4.11,6.16,9.66,6.16,16.66ZM320.45,48.42c0-3.53-1.1-6.4-3.3-8.6s-5.32-3.3-9.35-3.3h-13.73v24.8h13.55c4.12,0,7.3-1.17,9.52-3.52,2.22-2.34,3.33-5.47,3.33-9.38Z"/>
|
||||||
|
<path class="cls-1" d="M343.56,25.87h11.91v29.3l30.89.09v-29.39h12v70.08h-12v-30.14l-30.89-.09v30.23h-11.91V25.87Z"/>
|
||||||
|
<path class="cls-1" d="M434.17,47.29c7.25,0,13.16,2.33,17.72,6.98,4.56,4.66,6.84,10.64,6.84,17.95s-2.28,13.25-6.84,17.91c-4.56,4.66-10.47,6.98-17.72,6.98s-13.25-2.33-17.81-6.98c-4.56-4.66-6.84-10.62-6.84-17.91s2.28-13.34,6.84-17.98c4.56-4.64,10.5-6.96,17.81-6.96ZM434.17,86.9c3.87,0,7.02-1.37,9.45-4.1,2.42-2.73,3.63-6.29,3.63-10.66s-1.21-7.91-3.63-10.62c-2.42-2.7-5.57-4.05-9.45-4.05s-7.17,1.35-9.61,4.05c-2.44,2.7-3.66,6.24-3.66,10.62s1.22,7.93,3.66,10.66c2.44,2.73,5.64,4.1,9.61,4.1Z"/>
|
||||||
|
<path class="cls-1" d="M540.67,65.81v30.14h-11.02v-28.41c0-3.28-.84-5.84-2.53-7.69-1.69-1.84-3.98-2.77-6.89-2.77-3.09,0-5.56,1.01-7.41,3.02-1.84,2.02-2.77,4.84-2.77,8.46v27.38h-11.16v-28.41c0-3.28-.82-5.84-2.46-7.69-1.64-1.84-3.91-2.77-6.82-2.77-3.09,0-5.58,1.01-7.45,3.02s-2.81,4.84-2.81,8.46v27.38h-11.34v-47.34h10.55l.38,4.55c2.75-4.03,7.23-6.05,13.45-6.05,3.62,0,6.77.75,9.42,2.25,2.66,1.5,4.67,3.69,6.05,6.56,1.16-2.75,3.07-4.91,5.74-6.47,2.67-1.56,5.85-2.34,9.54-2.34,5.37,0,9.64,1.66,12.8,4.97,3.16,3.31,4.73,7.89,4.73,13.73Z"/>
|
||||||
|
<path class="cls-1" d="M596.64,76.45h-36.28c.38,3.56,1.72,6.28,4.03,8.16,2.31,1.88,5.25,2.81,8.81,2.81,5.78,0,9.83-2.41,12.14-7.22l9.47,3.75c-1.78,4.16-4.59,7.41-8.41,9.75-3.83,2.34-8.23,3.52-13.2,3.52-7,0-12.68-2.29-17.04-6.87-4.36-4.58-6.54-10.59-6.54-18.02s2.2-13.48,6.59-18.14c4.39-4.66,10.13-6.98,17.23-6.98s12.58,2.3,16.83,6.89c4.25,4.59,6.38,10.64,6.38,18.14v4.22ZM560.55,68.48h24.56c-.22-3.84-1.38-6.77-3.49-8.79s-4.95-3.02-8.51-3.02-6.41,1.02-8.62,3.07c-2.22,2.05-3.53,4.96-3.94,8.74Z"/>
|
||||||
|
</g>
|
||||||
|
<path class="cls-1" d="M114.7,51.58L65.3,2.19c-2.92-2.92-7.69-2.92-10.61,0L5.3,51.58c-2.92,2.92-5.3,8.68-5.3,12.8v45c0,4.12,3.38,7.5,7.5,7.5h29.5V42.21c0-1.66,1.34-3,3-3h40c1.66,0,3,1.34,3,3v12c0,1.66-1.34,3-3,3h-25v6h25c1.66,0,3,1.34,3,3v12c0,1.66-1.34,3-3,3h-25v6h25c1.66,0,3,1.34,3,3v12c0,1.66-1.34,3-3,3h-28c-1.66,0-3-1.34-3-3s1.34-3,3-3h25v-6h-25c-1.66,0-3-1.34-3-3v-12c0-1.66,1.34-3,3-3h25v-6h-25c-1.66,0-3-1.34-3-3v-12c0-1.66,1.34-3,3-3h25v-6h-34v71.67h69.5c4.12,0,7.5-3.38,7.5-7.5v-45c0-4.12-2.39-9.89-5.3-12.8Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
|
@ -1,9 +1,10 @@
|
||||||
color:
|
|
||||||
- id: light_blue
|
|
||||||
hex: "3340FF"
|
|
||||||
|
|
||||||
lvgl:
|
lvgl:
|
||||||
|
log_level: TRACE
|
||||||
bg_color: light_blue
|
bg_color: light_blue
|
||||||
|
touchscreens:
|
||||||
|
- touchscreen_id: tft_touch
|
||||||
|
long_press_repeat_time: 200ms
|
||||||
|
long_press_time: 500ms
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
text: Hello world
|
text: Hello world
|
||||||
|
@ -17,8 +18,101 @@ lvgl:
|
||||||
text_color: 0xFFFFFF
|
text_color: 0xFFFFFF
|
||||||
align: bottom_mid
|
align: bottom_mid
|
||||||
text_font: space16
|
text_font: space16
|
||||||
|
- obj:
|
||||||
|
align: center
|
||||||
|
arc_opa: COVER
|
||||||
|
arc_color: 0xFF0000
|
||||||
|
arc_rounded: false
|
||||||
|
arc_width: 3
|
||||||
|
anim_time: 1s
|
||||||
|
bg_color: light_blue
|
||||||
|
bg_grad_color: light_blue
|
||||||
|
bg_dither_mode: ordered
|
||||||
|
bg_grad_dir: hor
|
||||||
|
bg_grad_stop: 128
|
||||||
|
bg_image_opa: transp
|
||||||
|
bg_image_recolor: light_blue
|
||||||
|
bg_image_recolor_opa: 50%
|
||||||
|
bg_main_stop: 0
|
||||||
|
bg_opa: 20%
|
||||||
|
border_color: 0x00FF00
|
||||||
|
border_opa: cover
|
||||||
|
border_post: true
|
||||||
|
border_side: [bottom, left]
|
||||||
|
border_width: 4
|
||||||
|
clip_corner: false
|
||||||
|
height: 50%
|
||||||
|
image_recolor: light_blue
|
||||||
|
image_recolor_opa: cover
|
||||||
|
line_width: 10
|
||||||
|
line_dash_width: 10
|
||||||
|
line_dash_gap: 10
|
||||||
|
line_rounded: false
|
||||||
|
line_color: light_blue
|
||||||
|
opa: cover
|
||||||
|
opa_layered: cover
|
||||||
|
outline_color: light_blue
|
||||||
|
outline_opa: cover
|
||||||
|
outline_pad: 10px
|
||||||
|
outline_width: 10px
|
||||||
|
pad_all: 10px
|
||||||
|
pad_bottom: 10px
|
||||||
|
pad_column: 10px
|
||||||
|
pad_left: 10px
|
||||||
|
pad_right: 10px
|
||||||
|
pad_row: 10px
|
||||||
|
pad_top: 10px
|
||||||
|
shadow_color: light_blue
|
||||||
|
shadow_ofs_x: 5
|
||||||
|
shadow_ofs_y: 5
|
||||||
|
shadow_opa: cover
|
||||||
|
shadow_spread: 5
|
||||||
|
shadow_width: 10
|
||||||
|
text_align: auto
|
||||||
|
text_color: light_blue
|
||||||
|
text_decor: [underline, strikethrough]
|
||||||
|
text_font: montserrat_18
|
||||||
|
text_letter_space: 4
|
||||||
|
text_line_space: 4
|
||||||
|
text_opa: cover
|
||||||
|
transform_angle: 180
|
||||||
|
transform_height: 100
|
||||||
|
transform_pivot_x: 50%
|
||||||
|
transform_pivot_y: 50%
|
||||||
|
transform_zoom: 0.5
|
||||||
|
translate_x: 10
|
||||||
|
translate_y: 10
|
||||||
|
max_height: 100
|
||||||
|
max_width: 200
|
||||||
|
min_height: 20%
|
||||||
|
min_width: 20%
|
||||||
|
radius: circle
|
||||||
|
width: 10px
|
||||||
|
x: 100
|
||||||
|
y: 120
|
||||||
|
- button:
|
||||||
|
width: 20%
|
||||||
|
height: 10%
|
||||||
|
pressed:
|
||||||
|
bg_color: light_blue
|
||||||
|
widgets:
|
||||||
|
- label:
|
||||||
|
text: Button
|
||||||
|
|
||||||
font:
|
font:
|
||||||
- file: "gfonts://Roboto"
|
- file: "gfonts://Roboto"
|
||||||
id: space16
|
id: space16
|
||||||
bpp: 4
|
bpp: 4
|
||||||
|
|
||||||
|
image:
|
||||||
|
- id: cat_img
|
||||||
|
resize: 256x48
|
||||||
|
file: $component_dir/logo-text.svg
|
||||||
|
- id: dog_img
|
||||||
|
file: $component_dir/logo-text.svg
|
||||||
|
resize: 256x48
|
||||||
|
type: TRANSPARENT_BINARY
|
||||||
|
|
||||||
|
color:
|
||||||
|
- id: light_blue
|
||||||
|
hex: "3340FF"
|
||||||
|
|
|
@ -19,7 +19,9 @@ display:
|
||||||
mirror_y: true
|
mirror_y: true
|
||||||
data_rate: 80MHz
|
data_rate: 80MHz
|
||||||
cs_pin: GPIO20
|
cs_pin: GPIO20
|
||||||
dc_pin: GPIO15
|
dc_pin:
|
||||||
|
number: GPIO15
|
||||||
|
ignore_strapping_warning: true
|
||||||
auto_clear_enabled: false
|
auto_clear_enabled: false
|
||||||
invert_colors: false
|
invert_colors: false
|
||||||
update_interval: never
|
update_interval: never
|
||||||
|
|
Loading…
Reference in a new issue