mirror of
https://github.com/esphome/esphome.git
synced 2025-08-09 11:57:46 +00:00
Merge branch 'dev' into idf_webserver_ota
This commit is contained in:
commit
9beebc7bfe
@ -248,6 +248,7 @@ esphome/components/libretiny_pwm/* @kuba2k2
|
|||||||
esphome/components/light/* @esphome/core
|
esphome/components/light/* @esphome/core
|
||||||
esphome/components/lightwaverf/* @max246
|
esphome/components/lightwaverf/* @max246
|
||||||
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
|
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
|
||||||
|
esphome/components/ln882x/* @lamauny
|
||||||
esphome/components/lock/* @esphome/core
|
esphome/components/lock/* @esphome/core
|
||||||
esphome/components/logger/* @esphome/core
|
esphome/components/logger/* @esphome/core
|
||||||
esphome/components/logger/select/* @clydebarrow
|
esphome/components/logger/select/* @clydebarrow
|
||||||
|
@ -34,11 +34,9 @@ from esphome.const import (
|
|||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
CONF_SUBSTITUTIONS,
|
CONF_SUBSTITUTIONS,
|
||||||
CONF_TOPIC,
|
CONF_TOPIC,
|
||||||
PLATFORM_BK72XX,
|
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_RTL87XX,
|
|
||||||
SECRETS_FILES,
|
SECRETS_FILES,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, EsphomeError, coroutine
|
from esphome.core import CORE, EsphomeError, coroutine
|
||||||
@ -354,7 +352,7 @@ def upload_program(config, args, host):
|
|||||||
if CORE.target_platform in (PLATFORM_RP2040):
|
if CORE.target_platform in (PLATFORM_RP2040):
|
||||||
return upload_using_platformio(config, args.device)
|
return upload_using_platformio(config, args.device)
|
||||||
|
|
||||||
if CORE.target_platform in (PLATFORM_BK72XX, PLATFORM_RTL87XX):
|
if CORE.is_libretiny:
|
||||||
return upload_using_platformio(config, host)
|
return upload_using_platformio(config, host)
|
||||||
|
|
||||||
return 1 # Unknown target platform
|
return 1 # Unknown target platform
|
||||||
|
@ -1537,6 +1537,8 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
|||||||
resp.manufacturer = "Raspberry Pi";
|
resp.manufacturer = "Raspberry Pi";
|
||||||
#elif defined(USE_BK72XX)
|
#elif defined(USE_BK72XX)
|
||||||
resp.manufacturer = "Beken";
|
resp.manufacturer = "Beken";
|
||||||
|
#elif defined(USE_LN882X)
|
||||||
|
resp.manufacturer = "Lightning";
|
||||||
#elif defined(USE_RTL87XX)
|
#elif defined(USE_RTL87XX)
|
||||||
resp.manufacturer = "Realtek";
|
resp.manufacturer = "Realtek";
|
||||||
#elif defined(USE_HOST)
|
#elif defined(USE_HOST)
|
||||||
|
@ -5,6 +5,7 @@ from esphome.const import (
|
|||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
@ -14,7 +15,15 @@ CODEOWNERS = ["@OttoWinter"]
|
|||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema({}),
|
cv.Schema({}),
|
||||||
cv.only_with_arduino,
|
cv.only_with_arduino,
|
||||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
|
cv.only_on(
|
||||||
|
[
|
||||||
|
PLATFORM_ESP32,
|
||||||
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_BK72XX,
|
||||||
|
PLATFORM_LN882X,
|
||||||
|
PLATFORM_RTL87XX,
|
||||||
|
]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ from esphome.const import (
|
|||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
@ -27,7 +28,15 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
|
cv.only_on(
|
||||||
|
[
|
||||||
|
PLATFORM_ESP32,
|
||||||
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_BK72XX,
|
||||||
|
PLATFORM_LN882X,
|
||||||
|
PLATFORM_RTL87XX,
|
||||||
|
]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ CONFIG_SCHEMA = (
|
|||||||
esp32=3232,
|
esp32=3232,
|
||||||
rp2040=2040,
|
rp2040=2040,
|
||||||
bk72xx=8892,
|
bk72xx=8892,
|
||||||
|
ln882x=8820,
|
||||||
rtl87xx=8892,
|
rtl87xx=8892,
|
||||||
): cv.port,
|
): cv.port,
|
||||||
cv.Optional(CONF_PASSWORD): cv.string,
|
cv.Optional(CONF_PASSWORD): cv.string,
|
||||||
|
@ -50,6 +50,7 @@ KEY_FAMILY = "family"
|
|||||||
|
|
||||||
# COMPONENTS - auto-generated! Do not modify this block.
|
# COMPONENTS - auto-generated! Do not modify this block.
|
||||||
COMPONENT_BK72XX = "bk72xx"
|
COMPONENT_BK72XX = "bk72xx"
|
||||||
|
COMPONENT_LN882X = "ln882x"
|
||||||
COMPONENT_RTL87XX = "rtl87xx"
|
COMPONENT_RTL87XX = "rtl87xx"
|
||||||
# COMPONENTS - end
|
# COMPONENTS - end
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ FAMILY_BK7231N = "BK7231N"
|
|||||||
FAMILY_BK7231Q = "BK7231Q"
|
FAMILY_BK7231Q = "BK7231Q"
|
||||||
FAMILY_BK7231T = "BK7231T"
|
FAMILY_BK7231T = "BK7231T"
|
||||||
FAMILY_BK7251 = "BK7251"
|
FAMILY_BK7251 = "BK7251"
|
||||||
|
FAMILY_LN882H = "LN882H"
|
||||||
FAMILY_RTL8710B = "RTL8710B"
|
FAMILY_RTL8710B = "RTL8710B"
|
||||||
FAMILY_RTL8720C = "RTL8720C"
|
FAMILY_RTL8720C = "RTL8720C"
|
||||||
FAMILIES = [
|
FAMILIES = [
|
||||||
@ -65,6 +67,7 @@ FAMILIES = [
|
|||||||
FAMILY_BK7231Q,
|
FAMILY_BK7231Q,
|
||||||
FAMILY_BK7231T,
|
FAMILY_BK7231T,
|
||||||
FAMILY_BK7251,
|
FAMILY_BK7251,
|
||||||
|
FAMILY_LN882H,
|
||||||
FAMILY_RTL8710B,
|
FAMILY_RTL8710B,
|
||||||
FAMILY_RTL8720C,
|
FAMILY_RTL8720C,
|
||||||
]
|
]
|
||||||
@ -73,6 +76,7 @@ FAMILY_FRIENDLY = {
|
|||||||
FAMILY_BK7231Q: "BK7231Q",
|
FAMILY_BK7231Q: "BK7231Q",
|
||||||
FAMILY_BK7231T: "BK7231T",
|
FAMILY_BK7231T: "BK7231T",
|
||||||
FAMILY_BK7251: "BK7251",
|
FAMILY_BK7251: "BK7251",
|
||||||
|
FAMILY_LN882H: "LN882H",
|
||||||
FAMILY_RTL8710B: "RTL8710B",
|
FAMILY_RTL8710B: "RTL8710B",
|
||||||
FAMILY_RTL8720C: "RTL8720C",
|
FAMILY_RTL8720C: "RTL8720C",
|
||||||
}
|
}
|
||||||
@ -81,6 +85,7 @@ FAMILY_COMPONENT = {
|
|||||||
FAMILY_BK7231Q: COMPONENT_BK72XX,
|
FAMILY_BK7231Q: COMPONENT_BK72XX,
|
||||||
FAMILY_BK7231T: COMPONENT_BK72XX,
|
FAMILY_BK7231T: COMPONENT_BK72XX,
|
||||||
FAMILY_BK7251: COMPONENT_BK72XX,
|
FAMILY_BK7251: COMPONENT_BK72XX,
|
||||||
|
FAMILY_LN882H: COMPONENT_LN882X,
|
||||||
FAMILY_RTL8710B: COMPONENT_RTL87XX,
|
FAMILY_RTL8710B: COMPONENT_RTL87XX,
|
||||||
FAMILY_RTL8720C: COMPONENT_RTL87XX,
|
FAMILY_RTL8720C: COMPONENT_RTL87XX,
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@ PIN_SCHEMA_EXTRA = f"libretiny.BASE_PIN_SCHEMA.extend({VAR_PIN_SCHEMA})"
|
|||||||
COMPONENT_MAP = {
|
COMPONENT_MAP = {
|
||||||
"rtl87xx": "realtek-amb",
|
"rtl87xx": "realtek-amb",
|
||||||
"bk72xx": "beken-72xx",
|
"bk72xx": "beken-72xx",
|
||||||
|
"ln882x": "lightning-ln882x",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
52
esphome/components/ln882x/__init__.py
Normal file
52
esphome/components/ln882x/__init__.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# This file was auto-generated by libretiny/generate_components.py
|
||||||
|
# Do not modify its contents.
|
||||||
|
# For custom pin validators, put validate_pin() or validate_usage()
|
||||||
|
# in gpio.py file in this directory.
|
||||||
|
# For changing schema/pin schema, put COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA
|
||||||
|
# in schema.py file in this directory.
|
||||||
|
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import libretiny
|
||||||
|
from esphome.components.libretiny.const import (
|
||||||
|
COMPONENT_LN882X,
|
||||||
|
KEY_COMPONENT_DATA,
|
||||||
|
KEY_LIBRETINY,
|
||||||
|
LibreTinyComponent,
|
||||||
|
)
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
|
from .boards import LN882X_BOARD_PINS, LN882X_BOARDS
|
||||||
|
|
||||||
|
CODEOWNERS = ["@lamauny"]
|
||||||
|
AUTO_LOAD = ["libretiny"]
|
||||||
|
IS_TARGET_PLATFORM = True
|
||||||
|
|
||||||
|
COMPONENT_DATA = LibreTinyComponent(
|
||||||
|
name=COMPONENT_LN882X,
|
||||||
|
boards=LN882X_BOARDS,
|
||||||
|
board_pins=LN882X_BOARD_PINS,
|
||||||
|
pin_validation=None,
|
||||||
|
usage_validation=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _set_core_data(config):
|
||||||
|
CORE.data[KEY_LIBRETINY] = {}
|
||||||
|
CORE.data[KEY_LIBRETINY][KEY_COMPONENT_DATA] = COMPONENT_DATA
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = libretiny.BASE_SCHEMA
|
||||||
|
|
||||||
|
PIN_SCHEMA = libretiny.gpio.BASE_PIN_SCHEMA
|
||||||
|
|
||||||
|
CONFIG_SCHEMA.prepend_extra(_set_core_data)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
return await libretiny.component_to_code(config)
|
||||||
|
|
||||||
|
|
||||||
|
@pins.PIN_SCHEMA_REGISTRY.register("ln882x", PIN_SCHEMA)
|
||||||
|
async def pin_to_code(config):
|
||||||
|
return await libretiny.gpio.component_pin_to_code(config)
|
285
esphome/components/ln882x/boards.py
Normal file
285
esphome/components/ln882x/boards.py
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
# This file was auto-generated by libretiny/generate_components.py
|
||||||
|
# Do not modify its contents.
|
||||||
|
|
||||||
|
from esphome.components.libretiny.const import FAMILY_LN882H
|
||||||
|
|
||||||
|
LN882X_BOARDS = {
|
||||||
|
"wl2s": {
|
||||||
|
"name": "WL2S Wi-Fi/BLE Module",
|
||||||
|
"family": FAMILY_LN882H,
|
||||||
|
},
|
||||||
|
"ln-02": {
|
||||||
|
"name": "LN-02 Wi-Fi/BLE Module",
|
||||||
|
"family": FAMILY_LN882H,
|
||||||
|
},
|
||||||
|
"generic-ln882hki": {
|
||||||
|
"name": "Generic - LN882HKI",
|
||||||
|
"family": FAMILY_LN882H,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
LN882X_BOARD_PINS = {
|
||||||
|
"wl2s": {
|
||||||
|
"WIRE0_SCL_0": 7,
|
||||||
|
"WIRE0_SCL_1": 12,
|
||||||
|
"WIRE0_SCL_2": 3,
|
||||||
|
"WIRE0_SCL_3": 10,
|
||||||
|
"WIRE0_SCL_4": 2,
|
||||||
|
"WIRE0_SCL_5": 0,
|
||||||
|
"WIRE0_SCL_6": 19,
|
||||||
|
"WIRE0_SCL_7": 11,
|
||||||
|
"WIRE0_SCL_8": 9,
|
||||||
|
"WIRE0_SCL_9": 24,
|
||||||
|
"WIRE0_SCL_10": 25,
|
||||||
|
"WIRE0_SCL_11": 5,
|
||||||
|
"WIRE0_SCL_12": 1,
|
||||||
|
"WIRE0_SDA_0": 7,
|
||||||
|
"WIRE0_SDA_1": 12,
|
||||||
|
"WIRE0_SDA_2": 3,
|
||||||
|
"WIRE0_SDA_3": 10,
|
||||||
|
"WIRE0_SDA_4": 2,
|
||||||
|
"WIRE0_SDA_5": 0,
|
||||||
|
"WIRE0_SDA_6": 19,
|
||||||
|
"WIRE0_SDA_7": 11,
|
||||||
|
"WIRE0_SDA_8": 9,
|
||||||
|
"WIRE0_SDA_9": 24,
|
||||||
|
"WIRE0_SDA_10": 25,
|
||||||
|
"WIRE0_SDA_11": 5,
|
||||||
|
"WIRE0_SDA_12": 1,
|
||||||
|
"SERIAL0_RX": 3,
|
||||||
|
"SERIAL0_TX": 2,
|
||||||
|
"SERIAL1_RX": 24,
|
||||||
|
"SERIAL1_TX": 25,
|
||||||
|
"ADC2": 0,
|
||||||
|
"ADC3": 1,
|
||||||
|
"ADC5": 19,
|
||||||
|
"PA00": 0,
|
||||||
|
"PA0": 0,
|
||||||
|
"PA01": 1,
|
||||||
|
"PA1": 1,
|
||||||
|
"PA02": 2,
|
||||||
|
"PA2": 2,
|
||||||
|
"PA03": 3,
|
||||||
|
"PA3": 3,
|
||||||
|
"PA05": 5,
|
||||||
|
"PA5": 5,
|
||||||
|
"PA07": 7,
|
||||||
|
"PA7": 7,
|
||||||
|
"PA09": 9,
|
||||||
|
"PA9": 9,
|
||||||
|
"PA10": 10,
|
||||||
|
"PA11": 11,
|
||||||
|
"PA12": 12,
|
||||||
|
"PB03": 19,
|
||||||
|
"PB3": 19,
|
||||||
|
"PB08": 24,
|
||||||
|
"PB8": 24,
|
||||||
|
"PB09": 25,
|
||||||
|
"PB9": 25,
|
||||||
|
"RX0": 3,
|
||||||
|
"RX1": 24,
|
||||||
|
"SCL0": 1,
|
||||||
|
"SDA0": 1,
|
||||||
|
"TX0": 2,
|
||||||
|
"TX1": 25,
|
||||||
|
"D0": 7,
|
||||||
|
"D1": 12,
|
||||||
|
"D2": 3,
|
||||||
|
"D3": 10,
|
||||||
|
"D4": 2,
|
||||||
|
"D5": 0,
|
||||||
|
"D6": 19,
|
||||||
|
"D7": 11,
|
||||||
|
"D8": 9,
|
||||||
|
"D9": 24,
|
||||||
|
"D10": 25,
|
||||||
|
"D11": 5,
|
||||||
|
"D12": 1,
|
||||||
|
"A0": 0,
|
||||||
|
"A1": 19,
|
||||||
|
"A2": 1,
|
||||||
|
},
|
||||||
|
"ln-02": {
|
||||||
|
"WIRE0_SCL_0": 11,
|
||||||
|
"WIRE0_SCL_1": 19,
|
||||||
|
"WIRE0_SCL_2": 3,
|
||||||
|
"WIRE0_SCL_3": 24,
|
||||||
|
"WIRE0_SCL_4": 2,
|
||||||
|
"WIRE0_SCL_5": 25,
|
||||||
|
"WIRE0_SCL_6": 1,
|
||||||
|
"WIRE0_SCL_7": 0,
|
||||||
|
"WIRE0_SCL_8": 9,
|
||||||
|
"WIRE0_SDA_0": 11,
|
||||||
|
"WIRE0_SDA_1": 19,
|
||||||
|
"WIRE0_SDA_2": 3,
|
||||||
|
"WIRE0_SDA_3": 24,
|
||||||
|
"WIRE0_SDA_4": 2,
|
||||||
|
"WIRE0_SDA_5": 25,
|
||||||
|
"WIRE0_SDA_6": 1,
|
||||||
|
"WIRE0_SDA_7": 0,
|
||||||
|
"WIRE0_SDA_8": 9,
|
||||||
|
"SERIAL0_RX": 3,
|
||||||
|
"SERIAL0_TX": 2,
|
||||||
|
"SERIAL1_RX": 24,
|
||||||
|
"SERIAL1_TX": 25,
|
||||||
|
"ADC2": 0,
|
||||||
|
"ADC3": 1,
|
||||||
|
"ADC5": 19,
|
||||||
|
"PA00": 0,
|
||||||
|
"PA0": 0,
|
||||||
|
"PA01": 1,
|
||||||
|
"PA1": 1,
|
||||||
|
"PA02": 2,
|
||||||
|
"PA2": 2,
|
||||||
|
"PA03": 3,
|
||||||
|
"PA3": 3,
|
||||||
|
"PA09": 9,
|
||||||
|
"PA9": 9,
|
||||||
|
"PA11": 11,
|
||||||
|
"PB03": 19,
|
||||||
|
"PB3": 19,
|
||||||
|
"PB08": 24,
|
||||||
|
"PB8": 24,
|
||||||
|
"PB09": 25,
|
||||||
|
"PB9": 25,
|
||||||
|
"RX0": 3,
|
||||||
|
"RX1": 24,
|
||||||
|
"SCL0": 9,
|
||||||
|
"SDA0": 9,
|
||||||
|
"TX0": 2,
|
||||||
|
"TX1": 25,
|
||||||
|
"D0": 11,
|
||||||
|
"D1": 19,
|
||||||
|
"D2": 3,
|
||||||
|
"D3": 24,
|
||||||
|
"D4": 2,
|
||||||
|
"D5": 25,
|
||||||
|
"D6": 1,
|
||||||
|
"D7": 0,
|
||||||
|
"D8": 9,
|
||||||
|
"A0": 19,
|
||||||
|
"A1": 1,
|
||||||
|
"A2": 0,
|
||||||
|
},
|
||||||
|
"generic-ln882hki": {
|
||||||
|
"WIRE0_SCL_0": 0,
|
||||||
|
"WIRE0_SCL_1": 1,
|
||||||
|
"WIRE0_SCL_2": 2,
|
||||||
|
"WIRE0_SCL_3": 3,
|
||||||
|
"WIRE0_SCL_4": 4,
|
||||||
|
"WIRE0_SCL_5": 5,
|
||||||
|
"WIRE0_SCL_6": 6,
|
||||||
|
"WIRE0_SCL_7": 7,
|
||||||
|
"WIRE0_SCL_8": 8,
|
||||||
|
"WIRE0_SCL_9": 9,
|
||||||
|
"WIRE0_SCL_10": 10,
|
||||||
|
"WIRE0_SCL_11": 11,
|
||||||
|
"WIRE0_SCL_12": 12,
|
||||||
|
"WIRE0_SCL_13": 19,
|
||||||
|
"WIRE0_SCL_14": 20,
|
||||||
|
"WIRE0_SCL_15": 21,
|
||||||
|
"WIRE0_SCL_16": 22,
|
||||||
|
"WIRE0_SCL_17": 23,
|
||||||
|
"WIRE0_SCL_18": 24,
|
||||||
|
"WIRE0_SCL_19": 25,
|
||||||
|
"WIRE0_SDA_0": 0,
|
||||||
|
"WIRE0_SDA_1": 1,
|
||||||
|
"WIRE0_SDA_2": 2,
|
||||||
|
"WIRE0_SDA_3": 3,
|
||||||
|
"WIRE0_SDA_4": 4,
|
||||||
|
"WIRE0_SDA_5": 5,
|
||||||
|
"WIRE0_SDA_6": 6,
|
||||||
|
"WIRE0_SDA_7": 7,
|
||||||
|
"WIRE0_SDA_8": 8,
|
||||||
|
"WIRE0_SDA_9": 9,
|
||||||
|
"WIRE0_SDA_10": 10,
|
||||||
|
"WIRE0_SDA_11": 11,
|
||||||
|
"WIRE0_SDA_12": 12,
|
||||||
|
"WIRE0_SDA_13": 19,
|
||||||
|
"WIRE0_SDA_14": 20,
|
||||||
|
"WIRE0_SDA_15": 21,
|
||||||
|
"WIRE0_SDA_16": 22,
|
||||||
|
"WIRE0_SDA_17": 23,
|
||||||
|
"WIRE0_SDA_18": 24,
|
||||||
|
"WIRE0_SDA_19": 25,
|
||||||
|
"SERIAL0_RX": 3,
|
||||||
|
"SERIAL0_TX": 2,
|
||||||
|
"SERIAL1_RX": 24,
|
||||||
|
"SERIAL1_TX": 25,
|
||||||
|
"ADC2": 0,
|
||||||
|
"ADC3": 1,
|
||||||
|
"ADC4": 4,
|
||||||
|
"ADC5": 19,
|
||||||
|
"ADC6": 20,
|
||||||
|
"ADC7": 21,
|
||||||
|
"PA00": 0,
|
||||||
|
"PA0": 0,
|
||||||
|
"PA01": 1,
|
||||||
|
"PA1": 1,
|
||||||
|
"PA02": 2,
|
||||||
|
"PA2": 2,
|
||||||
|
"PA03": 3,
|
||||||
|
"PA3": 3,
|
||||||
|
"PA04": 4,
|
||||||
|
"PA4": 4,
|
||||||
|
"PA05": 5,
|
||||||
|
"PA5": 5,
|
||||||
|
"PA06": 6,
|
||||||
|
"PA6": 6,
|
||||||
|
"PA07": 7,
|
||||||
|
"PA7": 7,
|
||||||
|
"PA08": 8,
|
||||||
|
"PA8": 8,
|
||||||
|
"PA09": 9,
|
||||||
|
"PA9": 9,
|
||||||
|
"PA10": 10,
|
||||||
|
"PA11": 11,
|
||||||
|
"PA12": 12,
|
||||||
|
"PB03": 19,
|
||||||
|
"PB3": 19,
|
||||||
|
"PB04": 20,
|
||||||
|
"PB4": 20,
|
||||||
|
"PB05": 21,
|
||||||
|
"PB5": 21,
|
||||||
|
"PB06": 22,
|
||||||
|
"PB6": 22,
|
||||||
|
"PB07": 23,
|
||||||
|
"PB7": 23,
|
||||||
|
"PB08": 24,
|
||||||
|
"PB8": 24,
|
||||||
|
"PB09": 25,
|
||||||
|
"PB9": 25,
|
||||||
|
"RX0": 3,
|
||||||
|
"RX1": 24,
|
||||||
|
"TX0": 2,
|
||||||
|
"TX1": 25,
|
||||||
|
"D0": 0,
|
||||||
|
"D1": 1,
|
||||||
|
"D2": 2,
|
||||||
|
"D3": 3,
|
||||||
|
"D4": 4,
|
||||||
|
"D5": 5,
|
||||||
|
"D6": 6,
|
||||||
|
"D7": 7,
|
||||||
|
"D8": 8,
|
||||||
|
"D9": 9,
|
||||||
|
"D10": 10,
|
||||||
|
"D11": 11,
|
||||||
|
"D12": 12,
|
||||||
|
"D13": 19,
|
||||||
|
"D14": 20,
|
||||||
|
"D15": 21,
|
||||||
|
"D16": 22,
|
||||||
|
"D17": 23,
|
||||||
|
"D18": 24,
|
||||||
|
"D19": 25,
|
||||||
|
"A2": 0,
|
||||||
|
"A3": 1,
|
||||||
|
"A4": 4,
|
||||||
|
"A5": 19,
|
||||||
|
"A6": 20,
|
||||||
|
"A7": 21,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
BOARDS = LN882X_BOARDS
|
@ -16,7 +16,11 @@ from esphome.components.esp32.const import (
|
|||||||
VARIANT_ESP32S3,
|
VARIANT_ESP32S3,
|
||||||
)
|
)
|
||||||
from esphome.components.libretiny import get_libretiny_component, get_libretiny_family
|
from esphome.components.libretiny import get_libretiny_component, get_libretiny_family
|
||||||
from esphome.components.libretiny.const import COMPONENT_BK72XX, COMPONENT_RTL87XX
|
from esphome.components.libretiny.const import (
|
||||||
|
COMPONENT_BK72XX,
|
||||||
|
COMPONENT_LN882X,
|
||||||
|
COMPONENT_RTL87XX,
|
||||||
|
)
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ARGS,
|
CONF_ARGS,
|
||||||
@ -35,6 +39,7 @@ from esphome.const import (
|
|||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
@ -100,6 +105,7 @@ UART_SELECTION_ESP8266 = [UART0, UART0_SWAP, UART1]
|
|||||||
|
|
||||||
UART_SELECTION_LIBRETINY = {
|
UART_SELECTION_LIBRETINY = {
|
||||||
COMPONENT_BK72XX: [DEFAULT, UART1, UART2],
|
COMPONENT_BK72XX: [DEFAULT, UART1, UART2],
|
||||||
|
COMPONENT_LN882X: [DEFAULT, UART0, UART1, UART2],
|
||||||
COMPONENT_RTL87XX: [DEFAULT, UART0, UART1, UART2],
|
COMPONENT_RTL87XX: [DEFAULT, UART0, UART1, UART2],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,6 +223,7 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
esp32_p4_idf=USB_SERIAL_JTAG,
|
esp32_p4_idf=USB_SERIAL_JTAG,
|
||||||
rp2040=USB_CDC,
|
rp2040=USB_CDC,
|
||||||
bk72xx=DEFAULT,
|
bk72xx=DEFAULT,
|
||||||
|
ln882x=DEFAULT,
|
||||||
rtl87xx=DEFAULT,
|
rtl87xx=DEFAULT,
|
||||||
): cv.All(
|
): cv.All(
|
||||||
cv.only_on(
|
cv.only_on(
|
||||||
@ -225,6 +232,7 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
@ -94,6 +94,7 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
|
|||||||
esp32="10000b",
|
esp32="10000b",
|
||||||
esp8266="1000b",
|
esp8266="1000b",
|
||||||
bk72xx="1000b",
|
bk72xx="1000b",
|
||||||
|
ln882x="1000b",
|
||||||
rtl87xx="1000b",
|
rtl87xx="1000b",
|
||||||
): cv.validate_bytes,
|
): cv.validate_bytes,
|
||||||
cv.Optional(CONF_FILTER, default="50us"): cv.All(
|
cv.Optional(CONF_FILTER, default="50us"): cv.All(
|
||||||
|
@ -7,6 +7,7 @@ from esphome.const import (
|
|||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
@ -33,6 +34,7 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
@ -16,6 +16,7 @@ CONFIG_SCHEMA = cv.Schema(
|
|||||||
esp32=IMPLEMENTATION_BSD_SOCKETS,
|
esp32=IMPLEMENTATION_BSD_SOCKETS,
|
||||||
rp2040=IMPLEMENTATION_LWIP_TCP,
|
rp2040=IMPLEMENTATION_LWIP_TCP,
|
||||||
bk72xx=IMPLEMENTATION_LWIP_SOCKETS,
|
bk72xx=IMPLEMENTATION_LWIP_SOCKETS,
|
||||||
|
ln882x=IMPLEMENTATION_LWIP_SOCKETS,
|
||||||
rtl87xx=IMPLEMENTATION_LWIP_SOCKETS,
|
rtl87xx=IMPLEMENTATION_LWIP_SOCKETS,
|
||||||
host=IMPLEMENTATION_BSD_SOCKETS,
|
host=IMPLEMENTATION_BSD_SOCKETS,
|
||||||
): cv.one_of(
|
): cv.one_of(
|
||||||
|
@ -28,6 +28,7 @@ from esphome.const import (
|
|||||||
PLATFORM_BK72XX,
|
PLATFORM_BK72XX,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
@ -174,7 +175,15 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
cv.Optional(CONF_SORTING_GROUPS): cv.ensure_list(sorting_group),
|
cv.Optional(CONF_SORTING_GROUPS): cv.ensure_list(sorting_group),
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
|
cv.only_on(
|
||||||
|
[
|
||||||
|
PLATFORM_ESP32,
|
||||||
|
PLATFORM_ESP8266,
|
||||||
|
PLATFORM_BK72XX,
|
||||||
|
PLATFORM_LN882X,
|
||||||
|
PLATFORM_RTL87XX,
|
||||||
|
]
|
||||||
|
),
|
||||||
default_url,
|
default_url,
|
||||||
validate_local,
|
validate_local,
|
||||||
validate_sorting_groups,
|
validate_sorting_groups,
|
||||||
|
@ -49,26 +49,69 @@ static const char *const HEADER_CORS_ALLOW_PNA = "Access-Control-Allow-Private-N
|
|||||||
UrlMatch match_url(const std::string &url, bool only_domain = false) {
|
UrlMatch match_url(const std::string &url, bool only_domain = false) {
|
||||||
UrlMatch match;
|
UrlMatch match;
|
||||||
match.valid = false;
|
match.valid = false;
|
||||||
size_t domain_end = url.find('/', 1);
|
match.domain = nullptr;
|
||||||
if (domain_end == std::string::npos)
|
match.id = nullptr;
|
||||||
|
match.method = nullptr;
|
||||||
|
match.domain_len = 0;
|
||||||
|
match.id_len = 0;
|
||||||
|
match.method_len = 0;
|
||||||
|
|
||||||
|
const char *url_ptr = url.c_str();
|
||||||
|
size_t url_len = url.length();
|
||||||
|
|
||||||
|
// URL must start with '/'
|
||||||
|
if (url_len < 2 || url_ptr[0] != '/')
|
||||||
return match;
|
return match;
|
||||||
match.domain = url.substr(1, domain_end - 1);
|
|
||||||
|
// Find domain
|
||||||
|
size_t domain_start = 1;
|
||||||
|
size_t domain_end = url.find('/', domain_start);
|
||||||
|
|
||||||
|
if (domain_end == std::string::npos) {
|
||||||
|
// URL is just "/domain"
|
||||||
|
match.domain = url_ptr + domain_start;
|
||||||
|
match.domain_len = url_len - domain_start;
|
||||||
|
match.valid = true;
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set domain
|
||||||
|
match.domain = url_ptr + domain_start;
|
||||||
|
match.domain_len = domain_end - domain_start;
|
||||||
|
|
||||||
if (only_domain) {
|
if (only_domain) {
|
||||||
match.valid = true;
|
match.valid = true;
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
if (url.length() == domain_end - 1)
|
|
||||||
|
// Check if there's anything after domain
|
||||||
|
if (url_len == domain_end + 1)
|
||||||
return match;
|
return match;
|
||||||
|
|
||||||
|
// Find ID
|
||||||
size_t id_begin = domain_end + 1;
|
size_t id_begin = domain_end + 1;
|
||||||
size_t id_end = url.find('/', id_begin);
|
size_t id_end = url.find('/', id_begin);
|
||||||
|
|
||||||
match.valid = true;
|
match.valid = true;
|
||||||
|
|
||||||
if (id_end == std::string::npos) {
|
if (id_end == std::string::npos) {
|
||||||
match.id = url.substr(id_begin, url.length() - id_begin);
|
// URL is "/domain/id" with no method
|
||||||
|
match.id = url_ptr + id_begin;
|
||||||
|
match.id_len = url_len - id_begin;
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
match.id = url.substr(id_begin, id_end - id_begin);
|
|
||||||
|
// Set ID
|
||||||
|
match.id = url_ptr + id_begin;
|
||||||
|
match.id_len = id_end - id_begin;
|
||||||
|
|
||||||
|
// Set method if present
|
||||||
size_t method_begin = id_end + 1;
|
size_t method_begin = id_end + 1;
|
||||||
match.method = url.substr(method_begin, url.length() - method_begin);
|
if (method_begin < url_len) {
|
||||||
|
match.method = url_ptr + method_begin;
|
||||||
|
match.method_len = url_len - method_begin;
|
||||||
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,9 +431,9 @@ void WebServer::on_sensor_update(sensor::Sensor *obj, float state) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (sensor::Sensor *obj : App.get_sensors()) {
|
for (sensor::Sensor *obj : App.get_sensors()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->sensor_json(obj, obj->state, detail);
|
std::string data = this->sensor_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -433,9 +476,9 @@ void WebServer::on_text_sensor_update(text_sensor::TextSensor *obj, const std::s
|
|||||||
}
|
}
|
||||||
void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (text_sensor::TextSensor *obj : App.get_text_sensors()) {
|
for (text_sensor::TextSensor *obj : App.get_text_sensors()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->text_sensor_json(obj, obj->state, detail);
|
std::string data = this->text_sensor_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -471,20 +514,20 @@ void WebServer::on_switch_update(switch_::Switch *obj, bool state) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (switch_::Switch *obj : App.get_switches()) {
|
for (switch_::Switch *obj : App.get_switches()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->switch_json(obj, obj->state, detail);
|
std::string data = this->switch_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method_equals("toggle")) {
|
||||||
this->schedule_([obj]() { obj->toggle(); });
|
this->schedule_([obj]() { obj->toggle(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "turn_on") {
|
} else if (match.method_equals("turn_on")) {
|
||||||
this->schedule_([obj]() { obj->turn_on(); });
|
this->schedule_([obj]() { obj->turn_on(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "turn_off") {
|
} else if (match.method_equals("turn_off")) {
|
||||||
this->schedule_([obj]() { obj->turn_off(); });
|
this->schedule_([obj]() { obj->turn_off(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else {
|
} else {
|
||||||
@ -514,13 +557,13 @@ std::string WebServer::switch_json(switch_::Switch *obj, bool value, JsonDetail
|
|||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (button::Button *obj : App.get_buttons()) {
|
for (button::Button *obj : App.get_buttons()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->button_json(obj, detail);
|
std::string data = this->button_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "press") {
|
} else if (match.method_equals("press")) {
|
||||||
this->schedule_([obj]() { obj->press(); });
|
this->schedule_([obj]() { obj->press(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
return;
|
return;
|
||||||
@ -555,9 +598,9 @@ void WebServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (binary_sensor::BinarySensor *obj : App.get_binary_sensors()) {
|
for (binary_sensor::BinarySensor *obj : App.get_binary_sensors()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->binary_sensor_json(obj, obj->state, detail);
|
std::string data = this->binary_sensor_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -593,18 +636,18 @@ void WebServer::on_fan_update(fan::Fan *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (fan::Fan *obj : App.get_fans()) {
|
for (fan::Fan *obj : App.get_fans()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->fan_json(obj, detail);
|
std::string data = this->fan_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method_equals("toggle")) {
|
||||||
this->schedule_([obj]() { obj->toggle().perform(); });
|
this->schedule_([obj]() { obj->toggle().perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "turn_on" || match.method == "turn_off") {
|
} else if (match.method_equals("turn_on") || match.method_equals("turn_off")) {
|
||||||
auto call = match.method == "turn_on" ? obj->turn_on() : obj->turn_off();
|
auto call = match.method_equals("turn_on") ? obj->turn_on() : obj->turn_off();
|
||||||
|
|
||||||
if (request->hasParam("speed_level")) {
|
if (request->hasParam("speed_level")) {
|
||||||
auto speed_level = request->getParam("speed_level")->value();
|
auto speed_level = request->getParam("speed_level")->value();
|
||||||
@ -674,17 +717,17 @@ void WebServer::on_light_update(light::LightState *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (light::LightState *obj : App.get_lights()) {
|
for (light::LightState *obj : App.get_lights()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->light_json(obj, detail);
|
std::string data = this->light_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method_equals("toggle")) {
|
||||||
this->schedule_([obj]() { obj->toggle().perform(); });
|
this->schedule_([obj]() { obj->toggle().perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "turn_on") {
|
} else if (match.method_equals("turn_on")) {
|
||||||
auto call = obj->turn_on();
|
auto call = obj->turn_on();
|
||||||
if (request->hasParam("brightness")) {
|
if (request->hasParam("brightness")) {
|
||||||
auto brightness = parse_number<float>(request->getParam("brightness")->value().c_str());
|
auto brightness = parse_number<float>(request->getParam("brightness")->value().c_str());
|
||||||
@ -741,7 +784,7 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
|
|
||||||
this->schedule_([call]() mutable { call.perform(); });
|
this->schedule_([call]() mutable { call.perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "turn_off") {
|
} else if (match.method_equals("turn_off")) {
|
||||||
auto call = obj->turn_off();
|
auto call = obj->turn_off();
|
||||||
if (request->hasParam("transition")) {
|
if (request->hasParam("transition")) {
|
||||||
auto transition = parse_number<uint32_t>(request->getParam("transition")->value().c_str());
|
auto transition = parse_number<uint32_t>(request->getParam("transition")->value().c_str());
|
||||||
@ -790,10 +833,10 @@ void WebServer::on_cover_update(cover::Cover *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (cover::Cover *obj : App.get_covers()) {
|
for (cover::Cover *obj : App.get_covers()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->cover_json(obj, detail);
|
std::string data = this->cover_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -801,15 +844,15 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
if (match.method == "open") {
|
if (match.method_equals("open")) {
|
||||||
call.set_command_open();
|
call.set_command_open();
|
||||||
} else if (match.method == "close") {
|
} else if (match.method_equals("close")) {
|
||||||
call.set_command_close();
|
call.set_command_close();
|
||||||
} else if (match.method == "stop") {
|
} else if (match.method_equals("stop")) {
|
||||||
call.set_command_stop();
|
call.set_command_stop();
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method_equals("toggle")) {
|
||||||
call.set_command_toggle();
|
call.set_command_toggle();
|
||||||
} else if (match.method != "set") {
|
} else if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -871,16 +914,16 @@ void WebServer::on_number_update(number::Number *obj, float state) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_numbers()) {
|
for (auto *obj : App.get_numbers()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->number_json(obj, obj->state, detail);
|
std::string data = this->number_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -942,15 +985,15 @@ void WebServer::on_date_update(datetime::DateEntity *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_dates()) {
|
for (auto *obj : App.get_dates()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->date_json(obj, detail);
|
std::string data = this->date_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1001,15 +1044,15 @@ void WebServer::on_time_update(datetime::TimeEntity *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_times()) {
|
for (auto *obj : App.get_times()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->time_json(obj, detail);
|
std::string data = this->time_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1059,15 +1102,15 @@ void WebServer::on_datetime_update(datetime::DateTimeEntity *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_datetimes()) {
|
for (auto *obj : App.get_datetimes()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->datetime_json(obj, detail);
|
std::string data = this->datetime_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1118,16 +1161,16 @@ void WebServer::on_text_update(text::Text *obj, const std::string &state) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_texts()) {
|
for (auto *obj : App.get_texts()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->text_json(obj, obj->state, detail);
|
std::string data = this->text_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1179,17 +1222,17 @@ void WebServer::on_select_update(select::Select *obj, const std::string &state,
|
|||||||
}
|
}
|
||||||
void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_selects()) {
|
for (auto *obj : App.get_selects()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->select_json(obj, obj->state, detail);
|
std::string data = this->select_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1238,17 +1281,17 @@ void WebServer::on_climate_update(climate::Climate *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_climate_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (auto *obj : App.get_climates()) {
|
for (auto *obj : App.get_climates()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->climate_json(obj, detail);
|
std::string data = this->climate_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match.method != "set") {
|
if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1397,20 +1440,20 @@ void WebServer::on_lock_update(lock::Lock *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (lock::Lock *obj : App.get_locks()) {
|
for (lock::Lock *obj : App.get_locks()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->lock_json(obj, obj->state, detail);
|
std::string data = this->lock_json(obj, obj->state, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "lock") {
|
} else if (match.method_equals("lock")) {
|
||||||
this->schedule_([obj]() { obj->lock(); });
|
this->schedule_([obj]() { obj->lock(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "unlock") {
|
} else if (match.method_equals("unlock")) {
|
||||||
this->schedule_([obj]() { obj->unlock(); });
|
this->schedule_([obj]() { obj->unlock(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else if (match.method == "open") {
|
} else if (match.method_equals("open")) {
|
||||||
this->schedule_([obj]() { obj->open(); });
|
this->schedule_([obj]() { obj->open(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else {
|
} else {
|
||||||
@ -1445,10 +1488,10 @@ void WebServer::on_valve_update(valve::Valve *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (valve::Valve *obj : App.get_valves()) {
|
for (valve::Valve *obj : App.get_valves()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->valve_json(obj, detail);
|
std::string data = this->valve_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -1456,15 +1499,15 @@ void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call = obj->make_call();
|
auto call = obj->make_call();
|
||||||
if (match.method == "open") {
|
if (match.method_equals("open")) {
|
||||||
call.set_command_open();
|
call.set_command_open();
|
||||||
} else if (match.method == "close") {
|
} else if (match.method_equals("close")) {
|
||||||
call.set_command_close();
|
call.set_command_close();
|
||||||
} else if (match.method == "stop") {
|
} else if (match.method_equals("stop")) {
|
||||||
call.set_command_stop();
|
call.set_command_stop();
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method_equals("toggle")) {
|
||||||
call.set_command_toggle();
|
call.set_command_toggle();
|
||||||
} else if (match.method != "set") {
|
} else if (!match.method_equals("set")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1517,10 +1560,10 @@ void WebServer::on_alarm_control_panel_update(alarm_control_panel::AlarmControlP
|
|||||||
}
|
}
|
||||||
void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (alarm_control_panel::AlarmControlPanel *obj : App.get_alarm_control_panels()) {
|
for (alarm_control_panel::AlarmControlPanel *obj : App.get_alarm_control_panels()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->alarm_control_panel_json(obj, obj->get_state(), detail);
|
std::string data = this->alarm_control_panel_json(obj, obj->get_state(), detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -1532,15 +1575,15 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques
|
|||||||
call.set_code(request->getParam("code")->value().c_str()); // NOLINT
|
call.set_code(request->getParam("code")->value().c_str()); // NOLINT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match.method == "disarm") {
|
if (match.method_equals("disarm")) {
|
||||||
call.disarm();
|
call.disarm();
|
||||||
} else if (match.method == "arm_away") {
|
} else if (match.method_equals("arm_away")) {
|
||||||
call.arm_away();
|
call.arm_away();
|
||||||
} else if (match.method == "arm_home") {
|
} else if (match.method_equals("arm_home")) {
|
||||||
call.arm_home();
|
call.arm_home();
|
||||||
} else if (match.method == "arm_night") {
|
} else if (match.method_equals("arm_night")) {
|
||||||
call.arm_night();
|
call.arm_night();
|
||||||
} else if (match.method == "arm_vacation") {
|
} else if (match.method_equals("arm_vacation")) {
|
||||||
call.arm_vacation();
|
call.arm_vacation();
|
||||||
} else {
|
} else {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@ -1584,10 +1627,10 @@ void WebServer::on_event(event::Event *obj, const std::string &event_type) {
|
|||||||
|
|
||||||
void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (event::Event *obj : App.get_events()) {
|
for (event::Event *obj : App.get_events()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->event_json(obj, "", detail);
|
std::string data = this->event_json(obj, "", detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
@ -1633,17 +1676,17 @@ void WebServer::on_update(update::UpdateEntity *obj) {
|
|||||||
}
|
}
|
||||||
void WebServer::handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
void WebServer::handle_update_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
for (update::UpdateEntity *obj : App.get_updates()) {
|
for (update::UpdateEntity *obj : App.get_updates()) {
|
||||||
if (obj->get_object_id() != match.id)
|
if (!match.id_equals(obj->get_object_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->method() == HTTP_GET && match.method.empty()) {
|
if (request->method() == HTTP_GET && match.method_empty()) {
|
||||||
auto detail = get_request_detail(request);
|
auto detail = get_request_detail(request);
|
||||||
std::string data = this->update_json(obj, detail);
|
std::string data = this->update_json(obj, detail);
|
||||||
request->send(200, "application/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match.method != "install") {
|
if (!match.method_equals("install")) {
|
||||||
request->send(404);
|
request->send(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1719,102 +1762,102 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) const {
|
|||||||
if (!match.valid)
|
if (!match.valid)
|
||||||
return false;
|
return false;
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
if (request->method() == HTTP_GET && match.domain == "sensor")
|
if (request->method() == HTTP_GET && match.domain_equals("sensor"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "switch")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("switch"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "button")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("button"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
if (request->method() == HTTP_GET && match.domain == "binary_sensor")
|
if (request->method() == HTTP_GET && match.domain_equals("binary_sensor"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_FAN
|
#ifdef USE_FAN
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "fan")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("fan"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "light")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("light"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
if (request->method() == HTTP_GET && match.domain == "text_sensor")
|
if (request->method() == HTTP_GET && match.domain_equals("text_sensor"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "cover")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("cover"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "number")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("number"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "date")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("date"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_TIME
|
#ifdef USE_DATETIME_TIME
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "time")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("time"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
#ifdef USE_DATETIME_DATETIME
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "datetime")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("datetime"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "text")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("text"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "select")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("select"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "climate")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("climate"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "lock")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("lock"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "valve")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("valve"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
if ((request->method() == HTTP_GET || request->method() == HTTP_POST) && match.domain == "alarm_control_panel")
|
if ((request->method() == HTTP_GET || request->method() == HTTP_POST) && match.domain_equals("alarm_control_panel"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_EVENT
|
#ifdef USE_EVENT
|
||||||
if (request->method() == HTTP_GET && match.domain == "event")
|
if (request->method() == HTTP_GET && match.domain_equals("event"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "update")
|
if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("update"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1856,112 +1899,112 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) {
|
|||||||
|
|
||||||
UrlMatch match = match_url(request->url().c_str()); // NOLINT
|
UrlMatch match = match_url(request->url().c_str()); // NOLINT
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
if (match.domain == "sensor") {
|
if (match.domain_equals("sensor")) {
|
||||||
this->handle_sensor_request(request, match);
|
this->handle_sensor_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
if (match.domain == "switch") {
|
if (match.domain_equals("switch")) {
|
||||||
this->handle_switch_request(request, match);
|
this->handle_switch_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
if (match.domain == "button") {
|
if (match.domain_equals("button")) {
|
||||||
this->handle_button_request(request, match);
|
this->handle_button_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
if (match.domain == "binary_sensor") {
|
if (match.domain_equals("binary_sensor")) {
|
||||||
this->handle_binary_sensor_request(request, match);
|
this->handle_binary_sensor_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_FAN
|
#ifdef USE_FAN
|
||||||
if (match.domain == "fan") {
|
if (match.domain_equals("fan")) {
|
||||||
this->handle_fan_request(request, match);
|
this->handle_fan_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
if (match.domain == "light") {
|
if (match.domain_equals("light")) {
|
||||||
this->handle_light_request(request, match);
|
this->handle_light_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
if (match.domain == "text_sensor") {
|
if (match.domain_equals("text_sensor")) {
|
||||||
this->handle_text_sensor_request(request, match);
|
this->handle_text_sensor_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
if (match.domain == "cover") {
|
if (match.domain_equals("cover")) {
|
||||||
this->handle_cover_request(request, match);
|
this->handle_cover_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
if (match.domain == "number") {
|
if (match.domain_equals("number")) {
|
||||||
this->handle_number_request(request, match);
|
this->handle_number_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
if (match.domain == "date") {
|
if (match.domain_equals("date")) {
|
||||||
this->handle_date_request(request, match);
|
this->handle_date_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_TIME
|
#ifdef USE_DATETIME_TIME
|
||||||
if (match.domain == "time") {
|
if (match.domain_equals("time")) {
|
||||||
this->handle_time_request(request, match);
|
this->handle_time_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
#ifdef USE_DATETIME_DATETIME
|
||||||
if (match.domain == "datetime") {
|
if (match.domain_equals("datetime")) {
|
||||||
this->handle_datetime_request(request, match);
|
this->handle_datetime_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
if (match.domain == "text") {
|
if (match.domain_equals("text")) {
|
||||||
this->handle_text_request(request, match);
|
this->handle_text_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
if (match.domain == "select") {
|
if (match.domain_equals("select")) {
|
||||||
this->handle_select_request(request, match);
|
this->handle_select_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
if (match.domain == "climate") {
|
if (match.domain_equals("climate")) {
|
||||||
this->handle_climate_request(request, match);
|
this->handle_climate_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
if (match.domain == "lock") {
|
if (match.domain_equals("lock")) {
|
||||||
this->handle_lock_request(request, match);
|
this->handle_lock_request(request, match);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1969,14 +2012,14 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
if (match.domain == "valve") {
|
if (match.domain_equals("valve")) {
|
||||||
this->handle_valve_request(request, match);
|
this->handle_valve_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
if (match.domain == "alarm_control_panel") {
|
if (match.domain_equals("alarm_control_panel")) {
|
||||||
this->handle_alarm_control_panel_request(request, match);
|
this->handle_alarm_control_panel_request(request, match);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1984,7 +2027,7 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
if (match.domain == "update") {
|
if (match.domain_equals("update")) {
|
||||||
this->handle_update_request(request, match);
|
this->handle_update_request(request, match);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -40,10 +40,28 @@ namespace web_server {
|
|||||||
|
|
||||||
/// Internal helper struct that is used to parse incoming URLs
|
/// Internal helper struct that is used to parse incoming URLs
|
||||||
struct UrlMatch {
|
struct UrlMatch {
|
||||||
std::string domain; ///< The domain of the component, for example "sensor"
|
const char *domain; ///< Pointer to domain within URL, for example "sensor"
|
||||||
std::string id; ///< The id of the device that's being accessed, for example "living_room_fan"
|
const char *id; ///< Pointer to id within URL, for example "living_room_fan"
|
||||||
std::string method; ///< The method that's being called, for example "turn_on"
|
const char *method; ///< Pointer to method within URL, for example "turn_on"
|
||||||
|
uint8_t domain_len; ///< Length of domain string
|
||||||
|
uint8_t id_len; ///< Length of id string
|
||||||
|
uint8_t method_len; ///< Length of method string
|
||||||
bool valid; ///< Whether this match is valid
|
bool valid; ///< Whether this match is valid
|
||||||
|
|
||||||
|
// Helper methods for string comparisons
|
||||||
|
bool domain_equals(const char *str) const {
|
||||||
|
return domain && domain_len == strlen(str) && memcmp(domain, str, domain_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool id_equals(const std::string &str) const {
|
||||||
|
return id && id_len == str.length() && memcmp(id, str.c_str(), id_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool method_equals(const char *str) const {
|
||||||
|
return method && method_len == strlen(str) && memcmp(method, str, method_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool method_empty() const { return method_len == 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_WEBSERVER_SORTING
|
#ifdef USE_WEBSERVER_SORTING
|
||||||
|
@ -309,6 +309,7 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
rp2040="light",
|
rp2040="light",
|
||||||
bk72xx="none",
|
bk72xx="none",
|
||||||
rtl87xx="none",
|
rtl87xx="none",
|
||||||
|
ln882x="light",
|
||||||
): cv.enum(WIFI_POWER_SAVE_MODES, upper=True),
|
): cv.enum(WIFI_POWER_SAVE_MODES, upper=True),
|
||||||
cv.Optional(CONF_FAST_CONNECT, default=False): cv.boolean,
|
cv.Optional(CONF_FAST_CONNECT, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
||||||
|
@ -12,6 +12,7 @@ PLATFORM_ESP32 = "esp32"
|
|||||||
PLATFORM_ESP8266 = "esp8266"
|
PLATFORM_ESP8266 = "esp8266"
|
||||||
PLATFORM_HOST = "host"
|
PLATFORM_HOST = "host"
|
||||||
PLATFORM_LIBRETINY_OLDSTYLE = "libretiny"
|
PLATFORM_LIBRETINY_OLDSTYLE = "libretiny"
|
||||||
|
PLATFORM_LN882X = "ln882x"
|
||||||
PLATFORM_RP2040 = "rp2040"
|
PLATFORM_RP2040 = "rp2040"
|
||||||
PLATFORM_RTL87XX = "rtl87xx"
|
PLATFORM_RTL87XX = "rtl87xx"
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ from esphome.const import (
|
|||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
PLATFORM_HOST,
|
PLATFORM_HOST,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
@ -661,9 +662,13 @@ class EsphomeCore:
|
|||||||
def is_rtl87xx(self):
|
def is_rtl87xx(self):
|
||||||
return self.target_platform == PLATFORM_RTL87XX
|
return self.target_platform == PLATFORM_RTL87XX
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_ln882x(self):
|
||||||
|
return self.target_platform == PLATFORM_LN882X
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_libretiny(self):
|
def is_libretiny(self):
|
||||||
return self.is_bk72xx or self.is_rtl87xx
|
return self.is_bk72xx or self.is_rtl87xx or self.is_ln882x
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_host(self):
|
def is_host(self):
|
||||||
|
@ -639,7 +639,11 @@ class DownloadListRequestHandler(BaseHandler):
|
|||||||
|
|
||||||
if platform.upper() in ESP32_VARIANTS:
|
if platform.upper() in ESP32_VARIANTS:
|
||||||
platform = "esp32"
|
platform = "esp32"
|
||||||
elif platform in (const.PLATFORM_RTL87XX, const.PLATFORM_BK72XX):
|
elif platform in (
|
||||||
|
const.PLATFORM_RTL87XX,
|
||||||
|
const.PLATFORM_BK72XX,
|
||||||
|
const.PLATFORM_LN882X,
|
||||||
|
):
|
||||||
platform = "libretiny"
|
platform = "libretiny"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -837,6 +841,10 @@ class BoardsRequestHandler(BaseHandler):
|
|||||||
from esphome.components.bk72xx.boards import BOARDS as BK72XX_BOARDS
|
from esphome.components.bk72xx.boards import BOARDS as BK72XX_BOARDS
|
||||||
|
|
||||||
boards = BK72XX_BOARDS
|
boards = BK72XX_BOARDS
|
||||||
|
elif platform == const.PLATFORM_LN882X:
|
||||||
|
from esphome.components.ln882x.boards import BOARDS as LN882X_BOARDS
|
||||||
|
|
||||||
|
boards = LN882X_BOARDS
|
||||||
elif platform == const.PLATFORM_RTL87XX:
|
elif platform == const.PLATFORM_RTL87XX:
|
||||||
from esphome.components.rtl87xx.boards import BOARDS as RTL87XX_BOARDS
|
from esphome.components.rtl87xx.boards import BOARDS as RTL87XX_BOARDS
|
||||||
|
|
||||||
|
@ -83,6 +83,11 @@ bk72xx:
|
|||||||
board: {board}
|
board: {board}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
LN882X_CONFIG = """
|
||||||
|
ln882x:
|
||||||
|
board: {board}
|
||||||
|
"""
|
||||||
|
|
||||||
RTL87XX_CONFIG = """
|
RTL87XX_CONFIG = """
|
||||||
rtl87xx:
|
rtl87xx:
|
||||||
board: {board}
|
board: {board}
|
||||||
@ -93,6 +98,7 @@ HARDWARE_BASE_CONFIGS = {
|
|||||||
"ESP32": ESP32_CONFIG,
|
"ESP32": ESP32_CONFIG,
|
||||||
"RP2040": RP2040_CONFIG,
|
"RP2040": RP2040_CONFIG,
|
||||||
"BK72XX": BK72XX_CONFIG,
|
"BK72XX": BK72XX_CONFIG,
|
||||||
|
"LN882X": LN882X_CONFIG,
|
||||||
"RTL87XX": RTL87XX_CONFIG,
|
"RTL87XX": RTL87XX_CONFIG,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +163,7 @@ def wizard_file(**kwargs):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=consider-using-f-string
|
# pylint: disable=consider-using-f-string
|
||||||
if kwargs["platform"] in ["ESP8266", "ESP32", "BK72XX", "RTL87XX"]:
|
if kwargs["platform"] in ["ESP8266", "ESP32", "BK72XX", "LN882X", "RTL87XX"]:
|
||||||
config += """
|
config += """
|
||||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||||
ap:
|
ap:
|
||||||
@ -181,6 +187,7 @@ def wizard_write(path, **kwargs):
|
|||||||
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.ln882x import boards as ln882x_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
|
from esphome.components.rtl87xx import boards as rtl87xx_boards
|
||||||
|
|
||||||
@ -200,6 +207,8 @@ def wizard_write(path, **kwargs):
|
|||||||
platform = "RP2040"
|
platform = "RP2040"
|
||||||
elif board in bk72xx_boards.BOARDS:
|
elif board in bk72xx_boards.BOARDS:
|
||||||
platform = "BK72XX"
|
platform = "BK72XX"
|
||||||
|
elif board in ln882x_boards.BOARDS:
|
||||||
|
platform = "LN882X"
|
||||||
elif board in rtl87xx_boards.BOARDS:
|
elif board in rtl87xx_boards.BOARDS:
|
||||||
platform = "RTL87XX"
|
platform = "RTL87XX"
|
||||||
else:
|
else:
|
||||||
@ -253,6 +262,7 @@ 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.ln882x import boards as ln882x_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
|
from esphome.components.rtl87xx import boards as rtl87xx_boards
|
||||||
|
|
||||||
@ -325,7 +335,7 @@ def wizard(path):
|
|||||||
"firmwares for it."
|
"firmwares for it."
|
||||||
)
|
)
|
||||||
|
|
||||||
wizard_platforms = ["ESP32", "ESP8266", "BK72XX", "RTL87XX", "RP2040"]
|
wizard_platforms = ["ESP32", "ESP8266", "BK72XX", "LN882X", "RTL87XX", "RP2040"]
|
||||||
safe_print(
|
safe_print(
|
||||||
"Please choose one of the supported microcontrollers "
|
"Please choose one of the supported microcontrollers "
|
||||||
"(Use ESP8266 for Sonoff devices)."
|
"(Use ESP8266 for Sonoff devices)."
|
||||||
@ -361,7 +371,7 @@ def wizard(path):
|
|||||||
board_link = (
|
board_link = (
|
||||||
"https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html"
|
"https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html"
|
||||||
)
|
)
|
||||||
elif platform in ["BK72XX", "RTL87XX"]:
|
elif platform in ["BK72XX", "LN882X", "RTL87XX"]:
|
||||||
board_link = "https://docs.libretiny.eu/docs/status/supported/"
|
board_link = "https://docs.libretiny.eu/docs/status/supported/"
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("Unknown platform!")
|
raise NotImplementedError("Unknown platform!")
|
||||||
@ -384,6 +394,9 @@ def wizard(path):
|
|||||||
elif platform == "BK72XX":
|
elif platform == "BK72XX":
|
||||||
safe_print(f'For example "{color(AnsiFore.BOLD_WHITE, "cb2s")}".')
|
safe_print(f'For example "{color(AnsiFore.BOLD_WHITE, "cb2s")}".')
|
||||||
boards_list = bk72xx_boards.BOARDS.items()
|
boards_list = bk72xx_boards.BOARDS.items()
|
||||||
|
elif platform == "LN882X":
|
||||||
|
safe_print(f'For example "{color(AnsiFore.BOLD_WHITE, "wl2s")}".')
|
||||||
|
boards_list = ln882x_boards.BOARDS.items()
|
||||||
elif platform == "RTL87XX":
|
elif platform == "RTL87XX":
|
||||||
safe_print(f'For example "{color(AnsiFore.BOLD_WHITE, "wr3")}".')
|
safe_print(f'For example "{color(AnsiFore.BOLD_WHITE, "wr3")}".')
|
||||||
boards_list = rtl87xx_boards.BOARDS.items()
|
boards_list = rtl87xx_boards.BOARDS.items()
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
; It's *not* used during runtime.
|
; It's *not* used during runtime.
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
default_envs = esp8266-arduino, esp32-arduino, esp32-idf, bk72xx-arduino
|
default_envs = esp8266-arduino, esp32-arduino, esp32-idf, bk72xx-arduino, ln882h-arduino
|
||||||
; Ideally, we want src_dir to be the root directory of the repository, to mimic the runtime build
|
; Ideally, we want src_dir to be the root directory of the repository, to mimic the runtime build
|
||||||
; environment as best as possible. Unfortunately, the ESP-IDF toolchain really doesn't like this
|
; environment as best as possible. Unfortunately, the ESP-IDF toolchain really doesn't like this
|
||||||
; being the root directory. Instead, set esphome/ as the source directory, all our sources are in
|
; being the root directory. Instead, set esphome/ as the source directory, all our sources are in
|
||||||
@ -530,6 +530,17 @@ build_flags =
|
|||||||
build_unflags =
|
build_unflags =
|
||||||
${common.build_unflags}
|
${common.build_unflags}
|
||||||
|
|
||||||
|
[env:ln882h-arduino]
|
||||||
|
extends = common:libretiny-arduino
|
||||||
|
board = generic-ln882hki
|
||||||
|
build_flags =
|
||||||
|
${common:libretiny-arduino.build_flags}
|
||||||
|
${flags:runtime.build_flags}
|
||||||
|
-DUSE_LN882X
|
||||||
|
-DUSE_LIBRETINY_VARIANT_LN882H
|
||||||
|
build_unflags =
|
||||||
|
${common.build_unflags}
|
||||||
|
|
||||||
[env:rtl87xxb-arduino]
|
[env:rtl87xxb-arduino]
|
||||||
extends = common:libretiny-arduino
|
extends = common:libretiny-arduino
|
||||||
board = generic-rtl8710bn-2mb-788k
|
board = generic-rtl8710bn-2mb-788k
|
||||||
|
4
tests/components/adc/test.ln882x-ard.yaml
Normal file
4
tests/components/adc/test.ln882x-ard.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
sensor:
|
||||||
|
- platform: adc
|
||||||
|
pin: PA0
|
||||||
|
name: Basic ADC Test
|
2
tests/components/binary_sensor/test.ln882x-ard.yaml
Normal file
2
tests/components/binary_sensor/test.ln882x-ard.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
common: !include common.yaml
|
1
tests/components/debug/test.ln882x-ard.yaml
Normal file
1
tests/components/debug/test.ln882x-ard.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<<: !include common.yaml
|
2
tests/components/homeassistant/test.ln882x-ard.yaml
Normal file
2
tests/components/homeassistant/test.ln882x-ard.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
common: !include common.yaml
|
1
tests/components/script/test.ln882x-ard.yaml
Normal file
1
tests/components/script/test.ln882x-ard.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<<: !include common.yaml
|
1
tests/components/sntp/test.ln882x-ard.yaml
Normal file
1
tests/components/sntp/test.ln882x-ard.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<<: !include common.yaml
|
2
tests/components/switch/test.ln882x-ard.yaml
Normal file
2
tests/components/switch/test.ln882x-ard.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
common: !include common.yaml
|
1
tests/components/syslog/test.ln882x-ard.yaml
Normal file
1
tests/components/syslog/test.ln882x-ard.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<<: !include common.yaml
|
2
tests/components/template/test.ln882x-ard.yaml
Normal file
2
tests/components/template/test.ln882x-ard.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
common: !include common.yaml
|
@ -0,0 +1,15 @@
|
|||||||
|
esphome:
|
||||||
|
name: componenttestespln882x
|
||||||
|
friendly_name: $component_name
|
||||||
|
|
||||||
|
ln882x:
|
||||||
|
board: generic-ln882hki
|
||||||
|
|
||||||
|
logger:
|
||||||
|
level: VERY_VERBOSE
|
||||||
|
|
||||||
|
packages:
|
||||||
|
component_under_test: !include
|
||||||
|
file: $component_test_file
|
||||||
|
vars:
|
||||||
|
component_test_file: $component_test_file
|
@ -20,6 +20,7 @@ from esphome.const import (
|
|||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
PLATFORM_ESP8266,
|
PLATFORM_ESP8266,
|
||||||
PLATFORM_HOST,
|
PLATFORM_HOST,
|
||||||
|
PLATFORM_LN882X,
|
||||||
PLATFORM_RP2040,
|
PLATFORM_RP2040,
|
||||||
PLATFORM_RTL87XX,
|
PLATFORM_RTL87XX,
|
||||||
)
|
)
|
||||||
@ -214,7 +215,8 @@ def hex_int__valid(value):
|
|||||||
("arduino", PLATFORM_RP2040, None, "20", "20", "20", "20"),
|
("arduino", PLATFORM_RP2040, None, "20", "20", "20", "20"),
|
||||||
("arduino", PLATFORM_BK72XX, None, "21", "21", "21", "21"),
|
("arduino", PLATFORM_BK72XX, None, "21", "21", "21", "21"),
|
||||||
("arduino", PLATFORM_RTL87XX, None, "22", "22", "22", "22"),
|
("arduino", PLATFORM_RTL87XX, None, "22", "22", "22", "22"),
|
||||||
("host", PLATFORM_HOST, None, "23", "23", "23", "23"),
|
("arduino", PLATFORM_LN882X, None, "23", "23", "23", "23"),
|
||||||
|
("host", PLATFORM_HOST, None, "24", "24", "24", "24"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_split_default(framework, platform, variant, full, idf, arduino, simple):
|
def test_split_default(framework, platform, variant, full, idf, arduino, simple):
|
||||||
@ -244,7 +246,8 @@ def test_split_default(framework, platform, variant, full, idf, arduino, simple)
|
|||||||
"rp2040": "20",
|
"rp2040": "20",
|
||||||
"bk72xx": "21",
|
"bk72xx": "21",
|
||||||
"rtl87xx": "22",
|
"rtl87xx": "22",
|
||||||
"host": "23",
|
"ln882x": "23",
|
||||||
|
"host": "24",
|
||||||
}
|
}
|
||||||
|
|
||||||
idf_mappings = {
|
idf_mappings = {
|
||||||
|
@ -8,6 +8,7 @@ import pytest
|
|||||||
from esphome.components.bk72xx.boards import BK72XX_BOARD_PINS
|
from esphome.components.bk72xx.boards import BK72XX_BOARD_PINS
|
||||||
from esphome.components.esp32.boards import ESP32_BOARD_PINS
|
from esphome.components.esp32.boards import ESP32_BOARD_PINS
|
||||||
from esphome.components.esp8266.boards import ESP8266_BOARD_PINS
|
from esphome.components.esp8266.boards import ESP8266_BOARD_PINS
|
||||||
|
from esphome.components.ln882x.boards import LN882X_BOARD_PINS
|
||||||
from esphome.components.rtl87xx.boards import RTL87XX_BOARD_PINS
|
from esphome.components.rtl87xx.boards import RTL87XX_BOARD_PINS
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
import esphome.wizard as wz
|
import esphome.wizard as wz
|
||||||
@ -187,6 +188,27 @@ def test_wizard_write_defaults_platform_from_board_bk72xx(
|
|||||||
assert "bk72xx:" in generated_config
|
assert "bk72xx:" in generated_config
|
||||||
|
|
||||||
|
|
||||||
|
def test_wizard_write_defaults_platform_from_board_ln882x(
|
||||||
|
default_config, tmp_path, monkeypatch
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
If the platform is not explicitly set, use "LN882X" if the board is one of LN882X boards
|
||||||
|
"""
|
||||||
|
# Given
|
||||||
|
del default_config["platform"]
|
||||||
|
default_config["board"] = [*LN882X_BOARD_PINS][0]
|
||||||
|
|
||||||
|
monkeypatch.setattr(wz, "write_file", MagicMock())
|
||||||
|
monkeypatch.setattr(CORE, "config_path", os.path.dirname(tmp_path))
|
||||||
|
|
||||||
|
# When
|
||||||
|
wz.wizard_write(tmp_path, **default_config)
|
||||||
|
|
||||||
|
# Then
|
||||||
|
generated_config = wz.write_file.call_args.args[1]
|
||||||
|
assert "ln882x:" in generated_config
|
||||||
|
|
||||||
|
|
||||||
def test_wizard_write_defaults_platform_from_board_rtl87xx(
|
def test_wizard_write_defaults_platform_from_board_rtl87xx(
|
||||||
default_config, tmp_path, monkeypatch
|
default_config, tmp_path, monkeypatch
|
||||||
):
|
):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user