1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-31 07:58:14 +01:00
2024-07-17 20:27:25 +02:00

149 lines
5.4 KiB
Python

from esphome.const import (
CONF_ID,
CONF_USE_ADDRESS,
CONF_TX_PIN,
CONF_RX_PIN,
CONF_USERNAME,
CONF_PASSWORD,
CONF_MODEL,
CONF_TRIGGER_ID,
CONF_ON_CONNECT,
CONF_ON_DISCONNECT,
)
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.core import coroutine_with_priority
from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option
from esphome import automation
CODEOWNERS = ["@oarcher"]
DEPENDENCIES = ["esp32"]
AUTO_LOAD = ["network"]
# following should be removed if conflicts are resolved (so we can have a wifi ap using modem)
CONFLICTS_WITH = ["wifi", "captive_portal", "ethernet"]
CONF_PIN_CODE = "pin_code"
CONF_APN = "apn"
CONF_DTR_PIN = "dtr_pin"
CONF_INIT_AT = "init_at"
CONF_ON_NOT_RESPONDING = "on_not_responding"
modem_ns = cg.esphome_ns.namespace("modem")
ModemComponent = modem_ns.class_("ModemComponent", cg.Component)
ModemState = modem_ns.enum("ModemState")
ModemOnNotRespondingTrigger = modem_ns.class_(
"ModemOnNotRespondingTrigger", automation.Trigger.template()
)
ModemOnConnectTrigger = modem_ns.class_(
"ModemOnConnectTrigger", automation.Trigger.template()
)
ModemOnDisconnectTrigger = modem_ns.class_(
"ModemOndisconnectTrigger", automation.Trigger.template()
)
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(ModemComponent),
cv.Required(CONF_TX_PIN): cv.positive_int,
cv.Required(CONF_RX_PIN): cv.positive_int,
cv.Required(CONF_MODEL): cv.string,
cv.Required(CONF_APN): cv.string,
cv.Optional(CONF_DTR_PIN): cv.positive_int,
cv.Optional(CONF_PIN_CODE): cv.string_strict,
cv.Optional(CONF_USERNAME): cv.string,
cv.Optional(CONF_PASSWORD): cv.string,
cv.Optional(CONF_USE_ADDRESS): cv.string,
cv.Optional(CONF_INIT_AT): cv.All(cv.ensure_list(cv.string)),
cv.Optional(CONF_ON_NOT_RESPONDING): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
ModemOnNotRespondingTrigger
)
}
),
cv.Optional(CONF_ON_CONNECT): automation.validate_automation(
{cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ModemOnConnectTrigger)}
),
cv.Optional(CONF_ON_DISCONNECT): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
ModemOnDisconnectTrigger
)
}
),
}
).extend(cv.COMPONENT_SCHEMA),
cv.require_framework_version(
esp_idf=cv.Version(4, 0, 0), # 5.2.0 OK
),
)
@coroutine_with_priority(60.0)
async def to_code(config):
add_idf_component(
name="esp_modem",
repo="https://github.com/espressif/esp-protocols.git",
ref="modem-v1.1.0",
path="components/esp_modem",
)
add_idf_sdkconfig_option("CONFIG_LWIP_DHCPS", False)
add_idf_sdkconfig_option("CONFIG_PPP", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_PPP_PAP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_PAP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD", True)
add_idf_sdkconfig_option("CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP", 0)
add_idf_sdkconfig_option("CONFIG_PPP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_PPP_NOTIFY_PHASE_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_PPP_CHAP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT", True)
# commented because cause crash if another UART is defined in the yaml
# If enabled, it should increase the reliability and the speed of the connection (TODO: test)
# add_idf_sdkconfig_option("CONFIG_UART_ISR_IN_IRAM", True)
cg.add_define("USE_MODEM")
var = cg.new_Pvariable(config[CONF_ID])
if use_address := config.get(CONF_USE_ADDRESS, None):
cg.add(var.set_use_address(use_address))
if username := config.get(CONF_USERNAME, None):
cg.add(var.set_username(username))
if password := config.get(CONF_PASSWORD, None):
cg.add(var.set_password(password))
if pin_code := config.get(CONF_PIN_CODE, None):
cg.add(var.set_pin_code(pin_code))
if init_at := config.get(CONF_INIT_AT, None):
for cmd in init_at:
cg.add(var.add_init_at_command(cmd))
cg.add(var.set_model(config[CONF_MODEL]))
cg.add(var.set_apn(config[CONF_APN]))
gpio_num_t = cg.global_ns.enum("gpio_num_t")
cg.add(var.set_rx_pin(getattr(gpio_num_t, f"GPIO_NUM_{config[CONF_RX_PIN]}")))
cg.add(var.set_tx_pin(getattr(gpio_num_t, f"GPIO_NUM_{config[CONF_TX_PIN]}")))
for conf in config.get(CONF_ON_NOT_RESPONDING, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
for conf in config.get(CONF_ON_CONNECT, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
for conf in config.get(CONF_ON_DISCONNECT, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
await cg.register_component(var, config)