mirror of https://github.com/esphome/esphome.git
165 lines
4.5 KiB
Python
165 lines
4.5 KiB
Python
import esphome.config_validation as cv
|
|
import esphome.codegen as cg
|
|
import esphome.automation as auto
|
|
from esphome.const import (
|
|
CONF_ID,
|
|
CONF_PRIORITY,
|
|
CONF_GROUP,
|
|
CONF_TRIGGER_ID,
|
|
CONF_ON_TURN_OFF,
|
|
CONF_VALUE,
|
|
)
|
|
from esphome.schema_extractors import (
|
|
SCHEMA_EXTRACT,
|
|
schema_extractor,
|
|
)
|
|
|
|
from esphome.core import coroutine_with_priority
|
|
|
|
CODEOWNERS = ["@nielsnl68"]
|
|
|
|
status_led_ns = cg.esphome_ns.namespace("status_indicator")
|
|
StatusIndicator = status_led_ns.class_("StatusIndicator", cg.Component)
|
|
StatusTrigger = status_led_ns.class_("StatusTrigger", auto.Trigger.template())
|
|
StatusAction = status_led_ns.class_("StatusAction", auto.Action)
|
|
CONF_TRIGGER_LIST = {
|
|
"on_app_error": True,
|
|
"on_clear_app_error": True,
|
|
"on_app_warning": True,
|
|
"on_clear_app_warning": True,
|
|
"on_network_connected": True,
|
|
"on_network_disconnected": True,
|
|
"on_wifi_ap_enabled": True,
|
|
"on_wifi_ap_disabled": True,
|
|
"on_api_connected": True,
|
|
"on_api_disconnected": True,
|
|
"on_mqtt_connected": True,
|
|
"on_mgtt_disconnected": True,
|
|
"on_custom_status": False,
|
|
}
|
|
CONF_WHICH = "which"
|
|
|
|
|
|
def trigger_setup(Single):
|
|
return auto.validate_automation(
|
|
{
|
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StatusTrigger),
|
|
cv.Optional(CONF_GROUP, default=""): cv.string,
|
|
cv.Optional(CONF_PRIORITY, default=0): cv.int_range(0, 10),
|
|
},
|
|
single=Single,
|
|
)
|
|
|
|
|
|
def add_default_triggers():
|
|
result = {}
|
|
|
|
for trigger, single in CONF_TRIGGER_LIST.items():
|
|
result[cv.Optional(trigger)] = trigger_setup(single)
|
|
return cv.Schema(result)
|
|
|
|
|
|
CONFIG_SCHEMA = (
|
|
cv.Schema(
|
|
{
|
|
cv.GenerateID(CONF_ID): cv.declare_id(StatusIndicator),
|
|
cv.Required(CONF_ON_TURN_OFF): trigger_setup(True),
|
|
}
|
|
)
|
|
.extend(cv.COMPONENT_SCHEMA)
|
|
.extend(add_default_triggers())
|
|
)
|
|
|
|
|
|
async def add_trigger(var, conf, key):
|
|
trigger = cg.new_Pvariable(
|
|
conf[CONF_TRIGGER_ID],
|
|
var,
|
|
conf[CONF_GROUP],
|
|
conf[CONF_PRIORITY],
|
|
conf[CONF_TRIGGER_ID].id,
|
|
)
|
|
await auto.build_automation(trigger, [], conf)
|
|
if key is not None:
|
|
cg.add(var.set_trigger(key, trigger))
|
|
|
|
|
|
@coroutine_with_priority(80.0)
|
|
async def to_code(config):
|
|
var = cg.new_Pvariable(config[CONF_ID])
|
|
await cg.register_component(var, config)
|
|
await add_trigger(var, config.get(CONF_ON_TURN_OFF), CONF_ON_TURN_OFF)
|
|
|
|
for trigger_name, single in CONF_TRIGGER_LIST.items():
|
|
conf = config.get(trigger_name, None)
|
|
if conf is not None:
|
|
if single:
|
|
await add_trigger(var, conf, trigger_name)
|
|
else:
|
|
for conf in config.get(trigger_name, []):
|
|
await add_trigger(var, conf, None)
|
|
|
|
|
|
def maybe_simple_valuex(*validators, **kwargs):
|
|
key = kwargs.pop("key", CONF_VALUE)
|
|
validator = cv.All(*validators)
|
|
|
|
@schema_extractor("maybe")
|
|
def validate(value):
|
|
if value == SCHEMA_EXTRACT:
|
|
return (validator, key)
|
|
|
|
if isinstance(value, dict):
|
|
return validator(value)
|
|
return validator({key: value})
|
|
|
|
return validate
|
|
|
|
|
|
@auto.register_action(
|
|
"status.push",
|
|
StatusAction,
|
|
maybe_simple_valuex(
|
|
{
|
|
cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator),
|
|
cv.Required(CONF_TRIGGER_ID): cv.use_id(StatusTrigger),
|
|
},
|
|
key=CONF_TRIGGER_ID,
|
|
),
|
|
)
|
|
async def status_action_push_to_code(config, action_id, template_arg, args):
|
|
var = cg.new_Pvariable(action_id, template_arg)
|
|
|
|
await cg.register_parented(var, config[CONF_ID])
|
|
|
|
cg.add(var.set_state(True))
|
|
trigger = await cg.get_variable(config[CONF_TRIGGER_ID])
|
|
cg.add(var.set_trigger(trigger))
|
|
return var
|
|
|
|
|
|
@auto.register_action(
|
|
"status.pop",
|
|
StatusAction,
|
|
maybe_simple_valuex(
|
|
{
|
|
cv.GenerateID(CONF_ID): cv.use_id(StatusIndicator),
|
|
cv.Optional(CONF_GROUP): cv.string,
|
|
cv.Optional(CONF_TRIGGER_ID): cv.use_id(StatusTrigger),
|
|
},
|
|
cv.has_exactly_one_key(CONF_GROUP, CONF_TRIGGER_ID),
|
|
key=CONF_TRIGGER_ID,
|
|
),
|
|
)
|
|
async def status_action_pop_to_code(config, action_id, template_arg, args):
|
|
var = cg.new_Pvariable(action_id, template_arg)
|
|
await cg.register_parented(var, config[CONF_ID])
|
|
cg.add(var.set_state(False))
|
|
if CONF_TRIGGER_ID in config:
|
|
trigger = await cg.get_variable(config[CONF_TRIGGER_ID])
|
|
cg.add(var.set_trigger(trigger))
|
|
else:
|
|
cg.add(var.set_group(config[CONF_GROUP]))
|
|
|
|
return var
|