fix schemas

This commit is contained in:
oarcher 2024-08-14 22:18:54 +02:00
parent 412ba4f60f
commit 77a30830c7
4 changed files with 85 additions and 46 deletions

View file

@ -32,6 +32,7 @@ AUTO_LOAD = ["network", "watchdog"]
CONFLICTS_WITH = ["captive_portal", "ethernet"] CONFLICTS_WITH = ["captive_portal", "ethernet"]
CONF_MODEM = "modem" CONF_MODEM = "modem"
CONF_MODEM_ID = "modem_id"
CONF_PIN_CODE = "pin_code" CONF_PIN_CODE = "pin_code"
CONF_APN = "apn" CONF_APN = "apn"
CONF_DTR_PIN = "dtr_pin" CONF_DTR_PIN = "dtr_pin"
@ -67,10 +68,14 @@ ModemOnDisconnectTrigger = modem_ns.class_(
"ModemOnDisconnectTrigger", automation.Trigger.template() "ModemOnDisconnectTrigger", automation.Trigger.template()
) )
MODEM_COMPONENT_SCHEMA = cv.Schema(
{cv.GenerateID(CONF_MODEM_ID): cv.use_id(ModemComponent)}
)
CONFIG_SCHEMA = cv.All( CONFIG_SCHEMA = cv.All(
cv.Schema( cv.Schema(
{ {
cv.GenerateID(): cv.declare_id(ModemComponent), cv.GenerateID(CONF_ID): cv.declare_id(ModemComponent),
cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_schema, cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_RX_PIN): pins.internal_gpio_output_pin_schema, cv.Required(CONF_RX_PIN): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_MODEL): cv.one_of(*MODEM_MODELS, upper=True), cv.Required(CONF_MODEL): cv.one_of(*MODEM_MODELS, upper=True),
@ -101,7 +106,9 @@ CONFIG_SCHEMA = cv.All(
} }
), ),
} }
).extend(cv.COMPONENT_SCHEMA), )
.extend(MODEM_COMPONENT_SCHEMA)
.extend(cv.COMPONENT_SCHEMA),
cv.require_framework_version( cv.require_framework_version(
esp_idf=cv.Version(4, 0, 0), # 5.2.0 OK esp_idf=cv.Version(4, 0, 0), # 5.2.0 OK
), ),
@ -109,10 +116,14 @@ CONFIG_SCHEMA = cv.All(
def final_validate_platform(config): def final_validate_platform(config):
if not fv.full_config.get().data.get(KEY_MODEM_CMUX, None): # to be called by platform components
if modem_config := fv.full_config.get().get(CONF_MODEM, None):
if not modem_config.get(CONF_ENABLE_CMUX, None):
raise cv.Invalid( raise cv.Invalid(
f"'{CONF_MODEM}' platform require '{CONF_ENABLE_CMUX}' to be 'true'." f"'{CONF_MODEM}' platform require '{CONF_ENABLE_CMUX}' to be 'true'."
) )
else:
raise cv.Invalid("'{CONF_MODEM}' component required.")
return config return config

View file

@ -18,9 +18,9 @@ from esphome.const import (
UNIT_METER, UNIT_METER,
UNIT_PERCENT, UNIT_PERCENT,
) )
import esphome.final_validate as fv
from .. import final_validate_platform, modem_ns, switch from .. import MODEM_COMPONENT_SCHEMA, final_validate_platform, modem_ns
from ..switch import GNSS_SWITCH_SCHEMA
CODEOWNERS = ["@oarcher"] CODEOWNERS = ["@oarcher"]
@ -45,6 +45,15 @@ ICON_SIGNAL_BAR = "mdi:signal"
ModemSensor = modem_ns.class_("ModemSensor", cg.PollingComponent) ModemSensor = modem_ns.class_("ModemSensor", cg.PollingComponent)
GNSS_SENSORS = {
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_ALTITUDE,
CONF_COURSE,
CONF_ACCURACY,
CONF_SPEED,
}
CONFIG_SCHEMA = cv.All( CONFIG_SCHEMA = cv.All(
cv.Schema( cv.Schema(
{ {
@ -69,51 +78,44 @@ CONFIG_SCHEMA = cv.All(
accuracy_decimals=5, accuracy_decimals=5,
icon=ICON_LATITUDE, icon=ICON_LATITUDE,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ).extend(GNSS_SWITCH_SCHEMA),
cv.Optional(CONF_LONGITUDE): sensor.sensor_schema( cv.Optional(CONF_LONGITUDE): sensor.sensor_schema(
unit_of_measurement=UNIT_DEGREES, unit_of_measurement=UNIT_DEGREES,
accuracy_decimals=5, accuracy_decimals=5,
icon=ICON_LONGITUDE, icon=ICON_LONGITUDE,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ).extend(GNSS_SWITCH_SCHEMA),
cv.Optional(CONF_ALTITUDE): sensor.sensor_schema( cv.Optional(CONF_ALTITUDE): sensor.sensor_schema(
unit_of_measurement=UNIT_METER, unit_of_measurement=UNIT_METER,
accuracy_decimals=1, accuracy_decimals=1,
icon=ICON_LOCATION_UP, icon=ICON_LOCATION_UP,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ).extend(GNSS_SWITCH_SCHEMA),
cv.Optional(CONF_SPEED): sensor.sensor_schema( cv.Optional(CONF_SPEED): sensor.sensor_schema(
unit_of_measurement=UNIT_KILOMETER_PER_HOUR, unit_of_measurement=UNIT_KILOMETER_PER_HOUR,
accuracy_decimals=1, accuracy_decimals=1,
icon=ICON_SPEED, icon=ICON_SPEED,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ).extend(GNSS_SWITCH_SCHEMA),
cv.Optional(CONF_ACCURACY): sensor.sensor_schema( cv.Optional(CONF_ACCURACY): sensor.sensor_schema(
unit_of_measurement=UNIT_METER, unit_of_measurement=UNIT_METER,
accuracy_decimals=1, accuracy_decimals=1,
icon=ICON_LOCATION_RADIUS, icon=ICON_LOCATION_RADIUS,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ).extend(GNSS_SWITCH_SCHEMA),
cv.Optional(CONF_COURSE): sensor.sensor_schema( cv.Optional(CONF_COURSE): sensor.sensor_schema(
unit_of_measurement=UNIT_DEGREES, unit_of_measurement=UNIT_DEGREES,
accuracy_decimals=1, accuracy_decimals=1,
icon=ICON_COMPASS, icon=ICON_COMPASS,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ).extend(GNSS_SWITCH_SCHEMA),
} }
).extend(cv.polling_component_schema("60s")) )
.extend(MODEM_COMPONENT_SCHEMA)
.extend(cv.polling_component_schema("60s")),
) )
FINAL_VALIDATE_SCHEMA = cv.All(final_validate_platform)
def _final_validate_gnss(config):
# GNSS sensors needs GNSS switch
if config.get(CONF_LATITUDE, None) or config.get(CONF_LONGITUDE, None):
if not fv.full_config.get().data.get(switch.KEY_MODEM_GNSS, None):
raise cv.Invalid("Using GNSS modem sensors require GNSS modem switch.")
return config
FINAL_VALIDATE_SCHEMA = cv.All(final_validate_platform, _final_validate_gnss)
async def to_code(config): async def to_code(config):

View file

@ -4,7 +4,13 @@ import esphome.config_validation as cv
from esphome.const import DEVICE_CLASS_SWITCH from esphome.const import DEVICE_CLASS_SWITCH
import esphome.final_validate as fv import esphome.final_validate as fv
from .. import KEY_MODEM_MODEL, final_validate_platform, modem_ns from .. import (
CONF_MODEL,
CONF_MODEM_ID,
MODEM_COMPONENT_SCHEMA,
final_validate_platform,
modem_ns,
)
CODEOWNERS = ["@oarcher"] CODEOWNERS = ["@oarcher"]
@ -17,8 +23,6 @@ IS_PLATFORM_COMPONENT = True
CONF_GNSS = "gnss" CONF_GNSS = "gnss"
CONF_GNSS_COMMAND = "gnss_command" # will be set by _final_validate_gnss CONF_GNSS_COMMAND = "gnss_command" # will be set by _final_validate_gnss
KEY_MODEM_GNSS = "modem_gnss"
ICON_SATELLITE = "mdi:satellite-variant" ICON_SATELLITE = "mdi:satellite-variant"
GnssSwitch = modem_ns.class_("GnssSwitch", switch.Switch, cg.Component) GnssSwitch = modem_ns.class_("GnssSwitch", switch.Switch, cg.Component)
@ -26,7 +30,15 @@ GnssSwitch = modem_ns.class_("GnssSwitch", switch.Switch, cg.Component)
# SIM70xx doesn't support AT+CGNSSINFO, so gnss is not available # SIM70xx doesn't support AT+CGNSSINFO, so gnss is not available
MODEM_MODELS_GNSS_COMMAND = {"SIM7600": "AT+CGPS", "SIM7670": "AT+CGNSSPWR"} MODEM_MODELS_GNSS_COMMAND = {"SIM7600": "AT+CGPS", "SIM7670": "AT+CGNSSPWR"}
CONFIG_SCHEMA = cv.Schema(
CONF_GNSS_SWITCH_ID = "gnss_switch_id"
GNSS_SWITCH_SCHEMA = cv.Schema(
{cv.GenerateID(CONF_GNSS_SWITCH_ID): cv.use_id(GnssSwitch)}
)
CONFIG_SCHEMA = (
cv.Schema(
{ {
cv.Optional(CONF_GNSS): switch.switch_schema( cv.Optional(CONF_GNSS): switch.switch_schema(
GnssSwitch, GnssSwitch,
@ -35,17 +47,29 @@ CONFIG_SCHEMA = cv.Schema(
icon=ICON_SATELLITE, icon=ICON_SATELLITE,
), ),
} }
).extend(cv.COMPONENT_SCHEMA) )
.extend(GNSS_SWITCH_SCHEMA)
.extend(MODEM_COMPONENT_SCHEMA)
.extend(cv.COMPONENT_SCHEMA)
)
def _final_validate_gnss(config): def _final_validate_gnss(config):
# get modem model from modem config, and add CONF_GNSS_COMMAND to config
if config.get(CONF_GNSS, None): if config.get(CONF_GNSS, None):
full_config = fv.full_config.get() fconf = fv.full_config.get()
modem_model = full_config.data.get(KEY_MODEM_MODEL, None) modem_path = fconf.get_path_for_id(config[CONF_MODEM_ID])[:-1]
modem_config = fconf.get_config_for_path(modem_path)
if modem_model := modem_config.get(CONF_MODEL, None):
if modem_model not in MODEM_MODELS_GNSS_COMMAND: if modem_model not in MODEM_MODELS_GNSS_COMMAND:
raise cv.Invalid(f"GNSS not supported for modem '{modem_model}'.") raise cv.Invalid(
f"GNSS not supported for modem '{modem_model}'. Supported models are %s",
", ".join(MODEM_MODELS_GNSS_COMMAND.keys()),
)
# is it allowed to add config option?
config[CONF_GNSS_COMMAND] = MODEM_MODELS_GNSS_COMMAND[modem_model] config[CONF_GNSS_COMMAND] = MODEM_MODELS_GNSS_COMMAND[modem_model]
full_config.data[KEY_MODEM_GNSS] = True
return config return config

View file

@ -3,7 +3,7 @@ from esphome.components import text_sensor
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_ID, DEVICE_CLASS_EMPTY from esphome.const import CONF_ID, DEVICE_CLASS_EMPTY
from .. import final_validate_platform, modem_ns from .. import MODEM_COMPONENT_SCHEMA, final_validate_platform, modem_ns
CODEOWNERS = ["@oarcher"] CODEOWNERS = ["@oarcher"]
@ -25,7 +25,9 @@ CONFIG_SCHEMA = cv.All(
device_class=DEVICE_CLASS_EMPTY, device_class=DEVICE_CLASS_EMPTY,
), ),
} }
).extend(cv.polling_component_schema("60s")) )
.extend(MODEM_COMPONENT_SCHEMA)
.extend(cv.polling_component_schema("60s"))
) )