mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 06:58:11 +01:00
Decentralize Automation Generator Code (#182)
* Decentralize Automation Generator Code * Lint
This commit is contained in:
parent
820067ae5a
commit
2d20a1c0fb
10 changed files with 546 additions and 365 deletions
|
@ -1,37 +1,15 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
|
||||||
from esphomeyaml import core
|
from esphomeyaml import core
|
||||||
from esphomeyaml.components import cover, deep_sleep, fan, output
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \
|
from esphomeyaml.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \
|
||||||
CONF_BELOW, CONF_BLUE, CONF_BRIGHTNESS, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, \
|
CONF_BELOW, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, \
|
||||||
CONF_EFFECT, CONF_ELSE, CONF_FLASH_LENGTH, CONF_GREEN, CONF_ID, CONF_IF, CONF_LAMBDA, \
|
CONF_ELSE, CONF_ID, CONF_IF, CONF_LAMBDA, \
|
||||||
CONF_LEVEL, CONF_OR, CONF_OSCILLATING, CONF_PAYLOAD, CONF_QOS, CONF_RANGE, CONF_RED, \
|
CONF_OR, CONF_RANGE, CONF_THEN, CONF_TRIGGER_ID
|
||||||
CONF_RETAIN, CONF_SPEED, CONF_THEN, CONF_TOPIC, CONF_TRANSITION_LENGTH, CONF_TRIGGER_ID, \
|
|
||||||
CONF_WHITE, CONF_COLOR_TEMPERATURE
|
|
||||||
from esphomeyaml.core import ESPHomeYAMLError
|
from esphomeyaml.core import ESPHomeYAMLError
|
||||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, add_job, \
|
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, add_job, \
|
||||||
bool_, esphomelib_ns, float_, get_variable, process_lambda, std_string, templatable, uint32, \
|
esphomelib_ns, float_, process_lambda, templatable, uint32
|
||||||
uint8
|
from esphomeyaml.util import ServiceRegistry
|
||||||
|
|
||||||
CONF_MQTT_PUBLISH = 'mqtt.publish'
|
|
||||||
CONF_LIGHT_TOGGLE = 'light.toggle'
|
|
||||||
CONF_LIGHT_TURN_OFF = 'light.turn_off'
|
|
||||||
CONF_LIGHT_TURN_ON = 'light.turn_on'
|
|
||||||
CONF_SWITCH_TOGGLE = 'switch.toggle'
|
|
||||||
CONF_SWITCH_TURN_OFF = 'switch.turn_off'
|
|
||||||
CONF_SWITCH_TURN_ON = 'switch.turn_on'
|
|
||||||
CONF_COVER_OPEN = 'cover.open'
|
|
||||||
CONF_COVER_CLOSE = 'cover.close'
|
|
||||||
CONF_COVER_STOP = 'cover.stop'
|
|
||||||
CONF_FAN_TOGGLE = 'fan.toggle'
|
|
||||||
CONF_FAN_TURN_OFF = 'fan.turn_off'
|
|
||||||
CONF_FAN_TURN_ON = 'fan.turn_on'
|
|
||||||
CONF_OUTPUT_TURN_ON = 'output.turn_on'
|
|
||||||
CONF_OUTPUT_TURN_OFF = 'output.turn_off'
|
|
||||||
CONF_OUTPUT_SET_LEVEL = 'output.set_level'
|
|
||||||
CONF_DEEP_SLEEP_ENTER = 'deep_sleep.enter'
|
|
||||||
CONF_DEEP_SLEEP_PREVENT = 'deep_sleep.prevent'
|
|
||||||
|
|
||||||
|
|
||||||
def maybe_simple_id(*validators):
|
def maybe_simple_id(*validators):
|
||||||
|
@ -50,107 +28,30 @@ def validate_recursive_condition(value):
|
||||||
|
|
||||||
|
|
||||||
def validate_recursive_action(value):
|
def validate_recursive_action(value):
|
||||||
return ACTIONS_SCHEMA(value)
|
value = cv.ensure_list(value)
|
||||||
|
for i, item in enumerate(value):
|
||||||
|
if not isinstance(item, dict):
|
||||||
|
raise vol.Invalid(u"Action must consist of key-value mapping! Got {}".format(item))
|
||||||
|
key = next((x for x in item if x != CONF_ACTION_ID), None)
|
||||||
|
if key is None:
|
||||||
|
raise vol.Invalid(u"Key missing from action! Got {}".format(item))
|
||||||
|
if key not in ACTION_REGISTRY:
|
||||||
|
raise vol.Invalid(u"Unable to find action with the name '{}', is the component loaded?"
|
||||||
|
u"".format(key))
|
||||||
|
item.setdefault(CONF_ACTION_ID, None)
|
||||||
|
key2 = next((x for x in item if x != CONF_ACTION_ID and x != key), None)
|
||||||
|
if key2 is not None:
|
||||||
|
raise vol.Invalid(u"Cannot have two actions in one item. Key {} overrides {}!"
|
||||||
|
u"".format(key, key2))
|
||||||
|
validator = ACTION_REGISTRY[key][0]
|
||||||
|
value[i] = {
|
||||||
|
CONF_ACTION_ID: cv.declare_variable_id(None)(item[CONF_ACTION_ID]),
|
||||||
|
key: validator(item[key])
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
ACTION_KEYS = [CONF_DELAY, CONF_MQTT_PUBLISH, CONF_LIGHT_TOGGLE, CONF_LIGHT_TURN_OFF,
|
ACTION_REGISTRY = ServiceRegistry()
|
||||||
CONF_LIGHT_TURN_ON, CONF_SWITCH_TOGGLE, CONF_SWITCH_TURN_OFF, CONF_SWITCH_TURN_ON,
|
|
||||||
CONF_LAMBDA, CONF_COVER_OPEN, CONF_COVER_CLOSE, CONF_COVER_STOP, CONF_FAN_TOGGLE,
|
|
||||||
CONF_FAN_TURN_OFF, CONF_FAN_TURN_ON, CONF_OUTPUT_TURN_ON, CONF_OUTPUT_TURN_OFF,
|
|
||||||
CONF_OUTPUT_SET_LEVEL, CONF_IF, CONF_DEEP_SLEEP_ENTER, CONF_DEEP_SLEEP_PREVENT]
|
|
||||||
|
|
||||||
ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
|
|
||||||
cv.GenerateID(CONF_ACTION_ID): cv.declare_variable_id(None),
|
|
||||||
vol.Optional(CONF_DELAY): cv.templatable(cv.positive_time_period_milliseconds),
|
|
||||||
vol.Optional(CONF_MQTT_PUBLISH): vol.Schema({
|
|
||||||
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
|
||||||
vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
|
|
||||||
vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos),
|
|
||||||
vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_LIGHT_TOGGLE): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_LIGHT_TURN_OFF): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_LIGHT_TURN_ON): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'):
|
|
||||||
cv.templatable(cv.positive_time_period_milliseconds),
|
|
||||||
vol.Exclusive(CONF_FLASH_LENGTH, 'transformer'):
|
|
||||||
cv.templatable(cv.positive_time_period_milliseconds),
|
|
||||||
vol.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage),
|
|
||||||
vol.Optional(CONF_RED): cv.templatable(cv.percentage),
|
|
||||||
vol.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
|
||||||
vol.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
|
||||||
vol.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
|
||||||
vol.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.positive_float),
|
|
||||||
vol.Optional(CONF_EFFECT): cv.templatable(cv.string),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_SWITCH_TOGGLE): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_SWITCH_TURN_OFF): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_SWITCH_TURN_ON): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_COVER_OPEN): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_COVER_CLOSE): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_COVER_STOP): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_COVER_OPEN): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_COVER_CLOSE): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_COVER_STOP): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_FAN_TOGGLE): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_FAN_TURN_OFF): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_FAN_TURN_ON): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
|
||||||
vol.Optional(CONF_SPEED): cv.templatable(fan.validate_fan_speed),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_OUTPUT_TURN_OFF): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_OUTPUT_TURN_ON): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None)
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_OUTPUT_SET_LEVEL): {
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
|
||||||
vol.Required(CONF_LEVEL): cv.percentage,
|
|
||||||
},
|
|
||||||
vol.Optional(CONF_DEEP_SLEEP_ENTER): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(deep_sleep.DeepSleepComponent),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_DEEP_SLEEP_PREVENT): maybe_simple_id({
|
|
||||||
vol.Required(CONF_ID): cv.use_variable_id(deep_sleep.DeepSleepComponent),
|
|
||||||
}),
|
|
||||||
vol.Optional(CONF_IF): vol.All({
|
|
||||||
vol.Required(CONF_CONDITION): validate_recursive_condition,
|
|
||||||
vol.Optional(CONF_THEN): validate_recursive_action,
|
|
||||||
vol.Optional(CONF_ELSE): validate_recursive_action,
|
|
||||||
}, cv.has_at_least_one_key(CONF_THEN, CONF_ELSE)),
|
|
||||||
vol.Optional(CONF_LAMBDA): cv.lambda_,
|
|
||||||
}, cv.has_exactly_one_key(*ACTION_KEYS))])
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
DelayAction = esphomelib_ns.DelayAction
|
DelayAction = esphomelib_ns.DelayAction
|
||||||
|
@ -195,7 +96,7 @@ AUTOMATION_SCHEMA = vol.Schema({
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(None),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(None),
|
||||||
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(None),
|
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(None),
|
||||||
vol.Optional(CONF_IF): CONDITIONS_SCHEMA,
|
vol.Optional(CONF_IF): CONDITIONS_SCHEMA,
|
||||||
vol.Required(CONF_THEN): ACTIONS_SCHEMA,
|
vol.Required(CONF_THEN): validate_recursive_action,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,227 +146,68 @@ def build_conditions(config, arg_type):
|
||||||
yield ArrayInitializer(*conditions)
|
yield ArrayInitializer(*conditions)
|
||||||
|
|
||||||
|
|
||||||
def build_action(full_config, arg_type):
|
DELAY_ACTION_SCHEMA = cv.templatable(cv.positive_time_period_milliseconds)
|
||||||
from esphomeyaml.components import light, mqtt, switch
|
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_DELAY, DELAY_ACTION_SCHEMA)
|
||||||
|
def delay_action_to_code(config, action_id, arg_type):
|
||||||
template_arg = TemplateArguments(arg_type)
|
template_arg = TemplateArguments(arg_type)
|
||||||
# Keep pylint from freaking out
|
rhs = App.register_component(DelayAction.new(template_arg))
|
||||||
var = None
|
type = DelayAction.template(template_arg)
|
||||||
action_id = full_config[CONF_ACTION_ID]
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
key, config = next((k, v) for k, v in full_config.items() if k in ACTION_KEYS)
|
for template_ in templatable(config, arg_type, uint32):
|
||||||
if key == CONF_DELAY:
|
yield
|
||||||
rhs = App.register_component(DelayAction.new(template_arg))
|
add(action.set_delay(template_))
|
||||||
type = DelayAction.template(template_arg)
|
yield action
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
|
||||||
for template_ in templatable(config, arg_type, uint32):
|
|
||||||
yield
|
|
||||||
add(action.set_delay(template_))
|
|
||||||
yield action
|
|
||||||
elif key == CONF_LAMBDA:
|
|
||||||
for lambda_ in process_lambda(config, [(arg_type, 'x')]):
|
|
||||||
yield None
|
|
||||||
rhs = LambdaAction.new(template_arg, lambda_)
|
|
||||||
type = LambdaAction.template(template_arg)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_MQTT_PUBLISH:
|
|
||||||
rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg)
|
|
||||||
type = mqtt.MQTTPublishAction.template(template_arg)
|
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
|
||||||
for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
|
|
||||||
yield None
|
|
||||||
add(action.set_topic(template_))
|
|
||||||
|
|
||||||
for template_ in templatable(config[CONF_PAYLOAD], arg_type, std_string):
|
|
||||||
|
IF_ACTION_SCHEMA = vol.All({
|
||||||
|
vol.Required(CONF_CONDITION): validate_recursive_condition,
|
||||||
|
vol.Optional(CONF_THEN): validate_recursive_action,
|
||||||
|
vol.Optional(CONF_ELSE): validate_recursive_action,
|
||||||
|
}, cv.has_at_least_one_key(CONF_THEN, CONF_ELSE))
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_IF, IF_ACTION_SCHEMA)
|
||||||
|
def if_action_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for conditions in build_conditions(config[CONF_CONDITION], arg_type):
|
||||||
|
yield None
|
||||||
|
rhs = IfAction.new(template_arg, conditions)
|
||||||
|
type = IfAction.template(template_arg)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
if CONF_THEN in config:
|
||||||
|
for actions in build_actions(config[CONF_THEN], arg_type):
|
||||||
yield None
|
yield None
|
||||||
add(action.set_payload(template_))
|
add(action.add_then(actions))
|
||||||
if CONF_QOS in config:
|
if CONF_ELSE in config:
|
||||||
for template_ in templatable(config[CONF_QOS], arg_type, uint8):
|
for actions in build_actions(config[CONF_ELSE], arg_type):
|
||||||
yield
|
|
||||||
add(action.set_qos(template_))
|
|
||||||
if CONF_RETAIN in config:
|
|
||||||
for template_ in templatable(config[CONF_RETAIN], arg_type, bool_):
|
|
||||||
yield None
|
|
||||||
add(action.set_retain(template_))
|
|
||||||
yield action
|
|
||||||
elif key == CONF_LIGHT_TOGGLE:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
yield None
|
||||||
rhs = var.make_toggle_action(template_arg)
|
add(action.add_else(actions))
|
||||||
type = light.ToggleAction.template(template_arg)
|
yield action
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
|
||||||
if CONF_TRANSITION_LENGTH in config:
|
|
||||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
LAMBDA_ACTION_SCHEMA = cv.lambda_
|
||||||
yield None
|
|
||||||
add(action.set_transition_length(template_))
|
|
||||||
yield action
|
@ACTION_REGISTRY.register(CONF_LAMBDA, LAMBDA_ACTION_SCHEMA)
|
||||||
elif key == CONF_LIGHT_TURN_OFF:
|
def lambda_action_to_code(config, action_id, arg_type):
|
||||||
for var in get_variable(config[CONF_ID]):
|
template_arg = TemplateArguments(arg_type)
|
||||||
yield None
|
for lambda_ in process_lambda(config, [(arg_type, 'x')]):
|
||||||
rhs = var.make_turn_off_action(template_arg)
|
yield None
|
||||||
type = light.TurnOffAction.template(template_arg)
|
rhs = LambdaAction.new(template_arg, lambda_)
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
type = LambdaAction.template(template_arg)
|
||||||
if CONF_TRANSITION_LENGTH in config:
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
|
||||||
yield None
|
|
||||||
add(action.set_transition_length(template_))
|
def build_action(full_config, arg_type):
|
||||||
yield action
|
action_id = full_config[CONF_ACTION_ID]
|
||||||
elif key == CONF_LIGHT_TURN_ON:
|
key, config = next((k, v) for k, v in full_config.items() if k in ACTION_REGISTRY)
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
builder = ACTION_REGISTRY[key][1]
|
||||||
rhs = var.make_turn_on_action(template_arg)
|
for result in builder(config, action_id, arg_type):
|
||||||
type = light.TurnOnAction.template(template_arg)
|
yield None
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
yield result
|
||||||
if CONF_TRANSITION_LENGTH in config:
|
|
||||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
|
||||||
yield None
|
|
||||||
add(action.set_transition_length(template_))
|
|
||||||
if CONF_FLASH_LENGTH in config:
|
|
||||||
for template_ in templatable(config[CONF_FLASH_LENGTH], arg_type, uint32):
|
|
||||||
yield None
|
|
||||||
add(action.set_flash_length(template_))
|
|
||||||
if CONF_BRIGHTNESS in config:
|
|
||||||
for template_ in templatable(config[CONF_BRIGHTNESS], arg_type, float_):
|
|
||||||
yield None
|
|
||||||
add(action.set_brightness(template_))
|
|
||||||
if CONF_RED in config:
|
|
||||||
for template_ in templatable(config[CONF_RED], arg_type, float_):
|
|
||||||
yield None
|
|
||||||
add(action.set_red(template_))
|
|
||||||
if CONF_GREEN in config:
|
|
||||||
for template_ in templatable(config[CONF_GREEN], arg_type, float_):
|
|
||||||
yield None
|
|
||||||
add(action.set_green(template_))
|
|
||||||
if CONF_BLUE in config:
|
|
||||||
for template_ in templatable(config[CONF_BLUE], arg_type, float_):
|
|
||||||
yield None
|
|
||||||
add(action.set_blue(template_))
|
|
||||||
if CONF_WHITE in config:
|
|
||||||
for template_ in templatable(config[CONF_WHITE], arg_type, float_):
|
|
||||||
yield None
|
|
||||||
add(action.set_white(template_))
|
|
||||||
if CONF_COLOR_TEMPERATURE in config:
|
|
||||||
for template_ in templatable(config[CONF_COLOR_TEMPERATURE], arg_type, float_):
|
|
||||||
yield None
|
|
||||||
add(action.set_color_temperature(template_))
|
|
||||||
if CONF_EFFECT in config:
|
|
||||||
for template_ in templatable(config[CONF_EFFECT], arg_type, std_string):
|
|
||||||
yield None
|
|
||||||
add(action.set_effect(template_))
|
|
||||||
yield action
|
|
||||||
elif key == CONF_SWITCH_TOGGLE:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_toggle_action(template_arg)
|
|
||||||
type = switch.ToggleAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_SWITCH_TURN_OFF:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_turn_off_action(template_arg)
|
|
||||||
type = switch.TurnOffAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_SWITCH_TURN_ON:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_turn_on_action(template_arg)
|
|
||||||
type = switch.TurnOnAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_COVER_OPEN:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_open_action(template_arg)
|
|
||||||
type = cover.OpenAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_COVER_CLOSE:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_close_action(template_arg)
|
|
||||||
type = cover.CloseAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_COVER_STOP:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_stop_action(template_arg)
|
|
||||||
type = cover.StopAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_FAN_TOGGLE:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_toggle_action(template_arg)
|
|
||||||
type = fan.ToggleAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_FAN_TURN_OFF:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_turn_off_action(template_arg)
|
|
||||||
type = fan.TurnOffAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_FAN_TURN_ON:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_turn_on_action(template_arg)
|
|
||||||
type = fan.TurnOnAction.template(arg_type)
|
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
|
||||||
if CONF_OSCILLATING in config:
|
|
||||||
for template_ in templatable(config[CONF_OSCILLATING], arg_type, bool_):
|
|
||||||
yield None
|
|
||||||
add(action.set_oscillating(template_))
|
|
||||||
if CONF_SPEED in config:
|
|
||||||
for template_ in templatable(config[CONF_SPEED], arg_type, fan.FanSpeed):
|
|
||||||
yield None
|
|
||||||
add(action.set_speed(template_))
|
|
||||||
yield action
|
|
||||||
elif key == CONF_OUTPUT_TURN_OFF:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_turn_off_action(template_arg)
|
|
||||||
type = output.TurnOffAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_OUTPUT_TURN_ON:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_turn_on_action(template_arg)
|
|
||||||
type = output.TurnOnAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_OUTPUT_SET_LEVEL:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_set_level_action(template_arg)
|
|
||||||
type = output.SetLevelAction.template(arg_type)
|
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
|
||||||
for template_ in templatable(config[CONF_LEVEL], arg_type, bool_):
|
|
||||||
yield None
|
|
||||||
add(action.set_level(template_))
|
|
||||||
yield action
|
|
||||||
elif key == CONF_IF:
|
|
||||||
for conditions in build_conditions(config[CONF_CONDITION], arg_type):
|
|
||||||
yield None
|
|
||||||
rhs = IfAction.new(template_arg, conditions)
|
|
||||||
type = IfAction.template(template_arg)
|
|
||||||
action = Pvariable(action_id, rhs, type=type)
|
|
||||||
if CONF_THEN in config:
|
|
||||||
for actions in build_actions(config[CONF_THEN], arg_type):
|
|
||||||
yield None
|
|
||||||
add(action.add_then(actions))
|
|
||||||
if CONF_ELSE in config:
|
|
||||||
for actions in build_actions(config[CONF_ELSE], arg_type):
|
|
||||||
yield None
|
|
||||||
add(action.add_else(actions))
|
|
||||||
yield action
|
|
||||||
elif key == CONF_DEEP_SLEEP_ENTER:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_enter_deep_sleep_action(template_arg)
|
|
||||||
type = deep_sleep.EnterDeepSleepAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
elif key == CONF_DEEP_SLEEP_PREVENT:
|
|
||||||
for var in get_variable(config[CONF_ID]):
|
|
||||||
yield None
|
|
||||||
rhs = var.make_prevent_deep_sleep_action(template_arg)
|
|
||||||
type = deep_sleep.PreventDeepSleepAction.template(arg_type)
|
|
||||||
yield Pvariable(action_id, rhs, type=type)
|
|
||||||
else:
|
|
||||||
raise ESPHomeYAMLError(u"Unsupported action {}".format(config))
|
|
||||||
|
|
||||||
|
|
||||||
def build_actions(config, arg_type):
|
def build_actions(config, arg_type):
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_INTERNAL
|
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_INTERNAL
|
||||||
from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component, add
|
from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component, add, \
|
||||||
|
TemplateArguments, get_variable
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
|
|
||||||
|
@ -37,3 +41,50 @@ def setup_cover(cover_obj, mqtt_obj, config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_COVER'
|
BUILD_FLAGS = '-DUSE_COVER'
|
||||||
|
|
||||||
|
CONF_COVER_OPEN = 'cover.open'
|
||||||
|
COVER_OPEN_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_COVER_OPEN, COVER_OPEN_ACTION_SCHEMA)
|
||||||
|
def cover_open_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_open_action(template_arg)
|
||||||
|
type = OpenAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_COVER_CLOSE = 'cover.close'
|
||||||
|
COVER_CLOSE_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_COVER_CLOSE, COVER_CLOSE_ACTION_SCHEMA)
|
||||||
|
def cover_close_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_close_action(template_arg)
|
||||||
|
type = CloseAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_COVER_STOP = 'cover.stop'
|
||||||
|
COVER_STOP_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_COVER_STOP, COVER_STOP_ACTION_SCHEMA)
|
||||||
|
def cover_stop_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_stop_action(template_arg)
|
||||||
|
type = StopAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from esphomeyaml import config_validation as cv, pins
|
from esphomeyaml import config_validation as cv, pins
|
||||||
|
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||||
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \
|
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \
|
||||||
CONF_SLEEP_DURATION, CONF_WAKEUP_PIN
|
CONF_SLEEP_DURATION, CONF_WAKEUP_PIN
|
||||||
from esphomeyaml.helpers import App, Pvariable, add, gpio_input_pin_expression, esphomelib_ns
|
from esphomeyaml.helpers import App, Pvariable, add, gpio_input_pin_expression, esphomelib_ns, \
|
||||||
|
TemplateArguments, get_variable
|
||||||
|
|
||||||
|
|
||||||
def validate_pin_number(value):
|
def validate_pin_number(value):
|
||||||
|
@ -57,3 +59,35 @@ def to_code(config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_DEEP_SLEEP'
|
BUILD_FLAGS = '-DUSE_DEEP_SLEEP'
|
||||||
|
|
||||||
|
|
||||||
|
CONF_DEEP_SLEEP_ENTER = 'deep_sleep.enter'
|
||||||
|
DEEP_SLEEP_ENTER_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(DeepSleepComponent),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_DEEP_SLEEP_ENTER, DEEP_SLEEP_ENTER_ACTION_SCHEMA)
|
||||||
|
def deep_sleep_enter_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_enter_deep_sleep_action(template_arg)
|
||||||
|
type = EnterDeepSleepAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_DEEP_SLEEP_PREVENT = 'deep_sleep.prevent'
|
||||||
|
DEEP_SLEEP_PREVENT_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(DeepSleepComponent),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_DEEP_SLEEP_PREVENT, DEEP_SLEEP_PREVENT_ACTION_SCHEMA)
|
||||||
|
def deep_sleep_prevent_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_prevent_deep_sleep_action(template_arg)
|
||||||
|
type = PreventDeepSleepAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_OSCILLATION_COMMAND_TOPIC, \
|
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_OSCILLATION_COMMAND_TOPIC, \
|
||||||
CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_INTERNAL
|
CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_INTERNAL, \
|
||||||
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component
|
CONF_SPEED, CONF_OSCILLATING
|
||||||
|
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component, \
|
||||||
|
TemplateArguments, get_variable, templatable, bool_
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
|
|
||||||
|
@ -66,3 +69,62 @@ def setup_fan(fan_obj, mqtt_obj, config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_FAN'
|
BUILD_FLAGS = '-DUSE_FAN'
|
||||||
|
|
||||||
|
|
||||||
|
CONF_FAN_TOGGLE = 'fan.toggle'
|
||||||
|
FAN_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_FAN_TOGGLE, FAN_TOGGLE_ACTION_SCHEMA)
|
||||||
|
def fan_toggle_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_toggle_action(template_arg)
|
||||||
|
type = ToggleAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_FAN_TURN_OFF = 'fan.turn_off'
|
||||||
|
FAN_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_FAN_TURN_OFF, FAN_TURN_OFF_ACTION_SCHEMA)
|
||||||
|
def fan_turn_off_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_off_action(template_arg)
|
||||||
|
type = TurnOffAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_FAN_TURN_ON = 'fan.turn_on'
|
||||||
|
FAN_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
||||||
|
vol.Optional(CONF_SPEED): cv.templatable(validate_fan_speed),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_FAN_TURN_ON, FAN_TURN_ON_ACTION_SCHEMA)
|
||||||
|
def fan_turn_on_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_on_action(template_arg)
|
||||||
|
type = TurnOnAction.template(arg_type)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
if CONF_OSCILLATING in config:
|
||||||
|
for template_ in templatable(config[CONF_OSCILLATING], arg_type, bool_):
|
||||||
|
yield None
|
||||||
|
add(action.set_oscillating(template_))
|
||||||
|
if CONF_SPEED in config:
|
||||||
|
for template_ in templatable(config[CONF_SPEED], arg_type, FanSpeed):
|
||||||
|
yield None
|
||||||
|
add(action.set_speed(template_))
|
||||||
|
yield action
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLORS, \
|
from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLORS, \
|
||||||
CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECTS, CONF_EFFECT_ID, \
|
CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECTS, CONF_EFFECT_ID, \
|
||||||
CONF_GAMMA_CORRECT, \
|
CONF_GAMMA_CORRECT, CONF_GREEN, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, \
|
||||||
CONF_GREEN, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, CONF_NUM_LEDS, \
|
CONF_NUM_LEDS, CONF_RANDOM, CONF_RED, CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, \
|
||||||
CONF_RANDOM, CONF_RED, CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, CONF_UPDATE_INTERVAL, \
|
CONF_UPDATE_INTERVAL, CONF_WHITE, CONF_WIDTH, CONF_FLASH_LENGTH, CONF_COLOR_TEMPERATURE, \
|
||||||
CONF_WHITE, CONF_WIDTH
|
CONF_EFFECT
|
||||||
from esphomeyaml.helpers import Application, ArrayInitializer, Pvariable, RawExpression, \
|
from esphomeyaml.helpers import Application, ArrayInitializer, Pvariable, RawExpression, \
|
||||||
StructInitializer, add, add_job, esphomelib_ns, process_lambda, setup_mqtt_component
|
StructInitializer, add, add_job, esphomelib_ns, process_lambda, setup_mqtt_component, \
|
||||||
|
get_variable, TemplateArguments, templatable, uint32, float_, std_string
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
|
|
||||||
|
@ -338,3 +340,111 @@ def setup_light(light_obj, mqtt_obj, config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_LIGHT'
|
BUILD_FLAGS = '-DUSE_LIGHT'
|
||||||
|
|
||||||
|
|
||||||
|
CONF_LIGHT_TOGGLE = 'light.toggle'
|
||||||
|
LIGHT_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_LIGHT_TOGGLE, LIGHT_TOGGLE_ACTION_SCHEMA)
|
||||||
|
def light_toggle_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_toggle_action(template_arg)
|
||||||
|
type = ToggleAction.template(template_arg)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
if CONF_TRANSITION_LENGTH in config:
|
||||||
|
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||||
|
yield None
|
||||||
|
add(action.set_transition_length(template_))
|
||||||
|
yield action
|
||||||
|
|
||||||
|
|
||||||
|
CONF_LIGHT_TURN_OFF = 'light.turn_off'
|
||||||
|
LIGHT_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_LIGHT_TURN_OFF, LIGHT_TURN_OFF_ACTION_SCHEMA)
|
||||||
|
def light_turn_off_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_off_action(template_arg)
|
||||||
|
type = TurnOffAction.template(template_arg)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
if CONF_TRANSITION_LENGTH in config:
|
||||||
|
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||||
|
yield None
|
||||||
|
add(action.set_transition_length(template_))
|
||||||
|
yield action
|
||||||
|
|
||||||
|
|
||||||
|
CONF_LIGHT_TURN_ON = 'light.turn_on'
|
||||||
|
LIGHT_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'):
|
||||||
|
cv.templatable(cv.positive_time_period_milliseconds),
|
||||||
|
vol.Exclusive(CONF_FLASH_LENGTH, 'transformer'):
|
||||||
|
cv.templatable(cv.positive_time_period_milliseconds),
|
||||||
|
vol.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage),
|
||||||
|
vol.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||||
|
vol.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||||
|
vol.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||||
|
vol.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||||
|
vol.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.positive_float),
|
||||||
|
vol.Optional(CONF_EFFECT): cv.templatable(cv.string),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_LIGHT_TURN_ON, LIGHT_TURN_ON_ACTION_SCHEMA)
|
||||||
|
def light_turn_on_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_on_action(template_arg)
|
||||||
|
type = TurnOnAction.template(template_arg)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
if CONF_TRANSITION_LENGTH in config:
|
||||||
|
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||||
|
yield None
|
||||||
|
add(action.set_transition_length(template_))
|
||||||
|
if CONF_FLASH_LENGTH in config:
|
||||||
|
for template_ in templatable(config[CONF_FLASH_LENGTH], arg_type, uint32):
|
||||||
|
yield None
|
||||||
|
add(action.set_flash_length(template_))
|
||||||
|
if CONF_BRIGHTNESS in config:
|
||||||
|
for template_ in templatable(config[CONF_BRIGHTNESS], arg_type, float_):
|
||||||
|
yield None
|
||||||
|
add(action.set_brightness(template_))
|
||||||
|
if CONF_RED in config:
|
||||||
|
for template_ in templatable(config[CONF_RED], arg_type, float_):
|
||||||
|
yield None
|
||||||
|
add(action.set_red(template_))
|
||||||
|
if CONF_GREEN in config:
|
||||||
|
for template_ in templatable(config[CONF_GREEN], arg_type, float_):
|
||||||
|
yield None
|
||||||
|
add(action.set_green(template_))
|
||||||
|
if CONF_BLUE in config:
|
||||||
|
for template_ in templatable(config[CONF_BLUE], arg_type, float_):
|
||||||
|
yield None
|
||||||
|
add(action.set_blue(template_))
|
||||||
|
if CONF_WHITE in config:
|
||||||
|
for template_ in templatable(config[CONF_WHITE], arg_type, float_):
|
||||||
|
yield None
|
||||||
|
add(action.set_white(template_))
|
||||||
|
if CONF_COLOR_TEMPERATURE in config:
|
||||||
|
for template_ in templatable(config[CONF_COLOR_TEMPERATURE], arg_type, float_):
|
||||||
|
yield None
|
||||||
|
add(action.set_color_temperature(template_))
|
||||||
|
if CONF_EFFECT in config:
|
||||||
|
for template_ in templatable(config[CONF_EFFECT], arg_type, std_string):
|
||||||
|
yield None
|
||||||
|
add(action.set_effect(template_))
|
||||||
|
yield action
|
||||||
|
|
|
@ -2,6 +2,7 @@ import re
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml.automation import ACTION_REGISTRY
|
||||||
from esphomeyaml import automation
|
from esphomeyaml import automation
|
||||||
from esphomeyaml.components import logger
|
from esphomeyaml.components import logger
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
|
@ -11,7 +12,8 @@ from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, C
|
||||||
CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_TOPIC, \
|
CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_TOPIC, \
|
||||||
CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE
|
CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE
|
||||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \
|
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \
|
||||||
StructInitializer, TemplateArguments, add, esphomelib_ns, optional, std_string
|
StructInitializer, TemplateArguments, add, esphomelib_ns, optional, std_string, templatable, \
|
||||||
|
uint8, bool_
|
||||||
|
|
||||||
|
|
||||||
def validate_message_just_topic(value):
|
def validate_message_just_topic(value):
|
||||||
|
@ -159,6 +161,39 @@ def to_code(config):
|
||||||
automation.build_automation(trigger, std_string, conf)
|
automation.build_automation(trigger, std_string, conf)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_MQTT_PUBLISH = 'mqtt.publish'
|
||||||
|
MQTT_PUBLISH_ACTION_SCHEMA = vol.Schema({
|
||||||
|
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||||
|
vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
|
||||||
|
vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos),
|
||||||
|
vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_MQTT_PUBLISH, MQTT_PUBLISH_ACTION_SCHEMA)
|
||||||
|
def mqtt_publish_action_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg)
|
||||||
|
type = MQTTPublishAction.template(template_arg)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
|
||||||
|
yield None
|
||||||
|
add(action.set_topic(template_))
|
||||||
|
|
||||||
|
for template_ in templatable(config[CONF_PAYLOAD], arg_type, std_string):
|
||||||
|
yield None
|
||||||
|
add(action.set_payload(template_))
|
||||||
|
if CONF_QOS in config:
|
||||||
|
for template_ in templatable(config[CONF_QOS], arg_type, uint8):
|
||||||
|
yield
|
||||||
|
add(action.set_qos(template_))
|
||||||
|
if CONF_RETAIN in config:
|
||||||
|
for template_ in templatable(config[CONF_RETAIN], arg_type, bool_):
|
||||||
|
yield None
|
||||||
|
add(action.set_retain(template_))
|
||||||
|
yield action
|
||||||
|
|
||||||
|
|
||||||
def required_build_flags(config):
|
def required_build_flags(config):
|
||||||
if CONF_SSL_FINGERPRINTS in config:
|
if CONF_SSL_FINGERPRINTS in config:
|
||||||
return '-DASYNC_TCP_SSL_ENABLED=1'
|
return '-DASYNC_TCP_SSL_ENABLED=1'
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
|
from esphomeyaml.components.power_supply import PowerSupplyComponent
|
||||||
from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY
|
from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY, CONF_ID, CONF_LEVEL
|
||||||
from esphomeyaml.helpers import add, esphomelib_ns, get_variable
|
from esphomeyaml.helpers import add, esphomelib_ns, get_variable, TemplateArguments, Pvariable, \
|
||||||
|
templatable, bool_
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
|
|
||||||
|
@ -46,3 +48,56 @@ def setup_output_platform(obj, config, skip_power_supply=False):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_OUTPUT'
|
BUILD_FLAGS = '-DUSE_OUTPUT'
|
||||||
|
|
||||||
|
|
||||||
|
CONF_OUTPUT_TURN_ON = 'output.turn_on'
|
||||||
|
OUTPUT_TURN_OFF_ACTION = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_OUTPUT_TURN_ON, OUTPUT_TURN_OFF_ACTION)
|
||||||
|
def output_turn_on_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_off_action(template_arg)
|
||||||
|
type = TurnOffAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_OUTPUT_TURN_OFF = 'output.turn_off'
|
||||||
|
OUTPUT_TURN_ON_ACTION = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_OUTPUT_TURN_OFF, OUTPUT_TURN_ON_ACTION)
|
||||||
|
def output_turn_off_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_on_action(template_arg)
|
||||||
|
type = TurnOnAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_OUTPUT_SET_LEVEL = 'output.set_level'
|
||||||
|
OUTPUT_SET_LEVEL_ACTION = vol.Schema({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
vol.Required(CONF_LEVEL): cv.percentage,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_OUTPUT_SET_LEVEL, OUTPUT_SET_LEVEL_ACTION)
|
||||||
|
def output_set_level_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_set_level_action(template_arg)
|
||||||
|
type = SetLevelAction.template(arg_type)
|
||||||
|
action = Pvariable(action_id, rhs, type=type)
|
||||||
|
for template_ in templatable(config[CONF_LEVEL], arg_type, bool_):
|
||||||
|
yield None
|
||||||
|
add(action.set_level(template_))
|
||||||
|
yield action
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_INVERTED, CONF_MQTT_ID, CONF_INTERNAL
|
from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_INVERTED, CONF_MQTT_ID, CONF_INTERNAL
|
||||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, setup_mqtt_component
|
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, setup_mqtt_component, \
|
||||||
|
TemplateArguments, get_variable
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
|
|
||||||
|
@ -50,3 +52,51 @@ def register_switch(var, config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_SWITCH'
|
BUILD_FLAGS = '-DUSE_SWITCH'
|
||||||
|
|
||||||
|
|
||||||
|
CONF_SWITCH_TOGGLE = 'switch.toggle'
|
||||||
|
SWITCH_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_SWITCH_TOGGLE, SWITCH_TOGGLE_ACTION_SCHEMA)
|
||||||
|
def switch_toggle_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_toggle_action(template_arg)
|
||||||
|
type = ToggleAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_SWITCH_TURN_OFF = 'switch.turn_off'
|
||||||
|
SWITCH_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_SWITCH_TURN_OFF, SWITCH_TURN_OFF_ACTION_SCHEMA)
|
||||||
|
def switch_turn_off_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_off_action(template_arg)
|
||||||
|
type = TurnOffAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_SWITCH_TURN_ON = 'switch.turn_on'
|
||||||
|
SWITCH_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
|
||||||
|
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ACTION_REGISTRY.register(CONF_SWITCH_TURN_ON, SWITCH_TURN_ON_ACTION_SCHEMA)
|
||||||
|
def switch_turn_on_to_code(config, action_id, arg_type):
|
||||||
|
template_arg = TemplateArguments(arg_type)
|
||||||
|
for var in get_variable(config[CONF_ID]):
|
||||||
|
yield None
|
||||||
|
rhs = var.make_turn_on_action(template_arg)
|
||||||
|
type = TurnOnAction.template(arg_type)
|
||||||
|
yield Pvariable(action_id, rhs, type=type)
|
||||||
|
|
|
@ -128,11 +128,7 @@ def validate_config(config):
|
||||||
def _comp_error(ex, domain, config):
|
def _comp_error(ex, domain, config):
|
||||||
result.add_error(_format_config_error(ex, domain, config), domain, config)
|
result.add_error(_format_config_error(ex, domain, config), domain, config)
|
||||||
|
|
||||||
try:
|
# Step 1: Load everything
|
||||||
result[CONF_ESPHOMEYAML] = core_config.CONFIG_SCHEMA(config[CONF_ESPHOMEYAML])
|
|
||||||
except vol.Invalid as ex:
|
|
||||||
_comp_error(ex, CONF_ESPHOMEYAML, config[CONF_ESPHOMEYAML])
|
|
||||||
|
|
||||||
for domain, conf in config.iteritems():
|
for domain, conf in config.iteritems():
|
||||||
domain = str(domain)
|
domain = str(domain)
|
||||||
if domain == CONF_ESPHOMEYAML or domain.startswith('.'):
|
if domain == CONF_ESPHOMEYAML or domain.startswith('.'):
|
||||||
|
@ -144,6 +140,39 @@ def validate_config(config):
|
||||||
result.add_error(u"Component not found: {}".format(domain), domain, conf)
|
result.add_error(u"Component not found: {}".format(domain), domain, conf)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not hasattr(component, 'PLATFORM_SCHEMA'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for p_config in conf:
|
||||||
|
if not isinstance(p_config, dict):
|
||||||
|
result.add_error(u"Platform schemas must have 'platform:' key", )
|
||||||
|
continue
|
||||||
|
p_name = p_config.get(u'platform')
|
||||||
|
if p_name is None:
|
||||||
|
result.add_error(u"No platform specified for {}".format(domain))
|
||||||
|
continue
|
||||||
|
p_domain = u'{}.{}'.format(domain, p_name)
|
||||||
|
platform = get_platform(domain, p_name)
|
||||||
|
if platform is None:
|
||||||
|
result.add_error(u"Platform not found: '{}'".format(p_domain), p_domain, p_config)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Step 2: Validate configuration
|
||||||
|
try:
|
||||||
|
result[CONF_ESPHOMEYAML] = core_config.CONFIG_SCHEMA(config[CONF_ESPHOMEYAML])
|
||||||
|
except vol.Invalid as ex:
|
||||||
|
_comp_error(ex, CONF_ESPHOMEYAML, config[CONF_ESPHOMEYAML])
|
||||||
|
|
||||||
|
for domain, conf in config.iteritems():
|
||||||
|
if domain == CONF_ESPHOMEYAML or domain.startswith('.'):
|
||||||
|
continue
|
||||||
|
if conf is None:
|
||||||
|
conf = {}
|
||||||
|
domain = str(domain)
|
||||||
|
component = get_component(domain)
|
||||||
|
if component is None:
|
||||||
|
continue
|
||||||
|
|
||||||
esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS)
|
esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS)
|
||||||
if core.ESP_PLATFORM not in esp_platforms:
|
if core.ESP_PLATFORM not in esp_platforms:
|
||||||
result.add_error(u"Component {} doesn't support {}.".format(domain, core.ESP_PLATFORM),
|
result.add_error(u"Component {} doesn't support {}.".format(domain, core.ESP_PLATFORM),
|
||||||
|
@ -174,16 +203,13 @@ def validate_config(config):
|
||||||
platforms = []
|
platforms = []
|
||||||
for p_config in conf:
|
for p_config in conf:
|
||||||
if not isinstance(p_config, dict):
|
if not isinstance(p_config, dict):
|
||||||
result.add_error(u"Platform schemas must have 'platform:' key", )
|
|
||||||
continue
|
continue
|
||||||
p_name = p_config.get(u'platform')
|
p_name = p_config.get(u'platform')
|
||||||
if p_name is None:
|
if p_name is None:
|
||||||
result.add_error(u"No platform specified for {}".format(domain))
|
|
||||||
continue
|
continue
|
||||||
p_domain = u'{}.{}'.format(domain, p_name)
|
p_domain = u'{}.{}'.format(domain, p_name)
|
||||||
platform = get_platform(domain, p_name)
|
platform = get_platform(domain, p_name)
|
||||||
if platform is None:
|
if platform is None:
|
||||||
result.add_error(u"Platform not found: '{}'".format(p_domain), p_domain, p_config)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
success = True
|
success = True
|
||||||
|
|
16
esphomeyaml/util.py
Normal file
16
esphomeyaml/util.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
class Registry(dict):
|
||||||
|
def register(self, name):
|
||||||
|
def decorator(fun):
|
||||||
|
self[name] = fun
|
||||||
|
return fun
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceRegistry(dict):
|
||||||
|
def register(self, name, validator):
|
||||||
|
def decorator(fun):
|
||||||
|
self[name] = (validator, fun)
|
||||||
|
return fun
|
||||||
|
|
||||||
|
return decorator
|
Loading…
Reference in a new issue