Smallish Update

This commit is contained in:
Otto Winter 2018-08-13 19:11:33 +02:00
parent 5680de79a9
commit 5170a7cdf4
No known key found for this signature in database
GPG Key ID: DB66C0BE6013F97E
63 changed files with 1797 additions and 1215 deletions

View File

@ -104,7 +104,12 @@ def run_miniterm(config, port, escape=False):
with serial.Serial(port, baudrate=baud_rate) as ser: with serial.Serial(port, baudrate=baud_rate) as ser:
while True: while True:
line = ser.readline().replace('\r', '').replace('\n', '') try:
raw = ser.readline()
except serial.SerialException:
_LOGGER.error("Serial port closed!")
return
line = raw.replace('\r', '').replace('\n', '')
time = datetime.now().time().strftime('[%H:%M:%S]') time = datetime.now().time().strftime('[%H:%M:%S]')
message = time + line message = time + line
if escape: if escape:

View File

@ -1,17 +1,18 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import cover, fan from esphomeyaml import core
from esphomeyaml.components import cover, deep_sleep, fan, output
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_BELOW, CONF_BLUE, CONF_BRIGHTNESS, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, \
CONF_BLUE, CONF_BRIGHTNESS, CONF_CONDITION_ID, CONF_DELAY, CONF_EFFECT, CONF_FLASH_LENGTH, \ CONF_EFFECT, CONF_ELSE, CONF_FLASH_LENGTH, CONF_GREEN, CONF_ID, CONF_IF, CONF_LAMBDA, \
CONF_GREEN, CONF_ID, CONF_IF, CONF_LAMBDA, CONF_OR, CONF_OSCILLATING, CONF_PAYLOAD, CONF_QOS, \ CONF_LEVEL, CONF_OR, CONF_OSCILLATING, CONF_PAYLOAD, CONF_QOS, CONF_RANGE, CONF_RED, \
CONF_RANGE, CONF_RED, CONF_RETAIN, CONF_SPEED, CONF_THEN, CONF_TOPIC, CONF_TRANSITION_LENGTH, \ CONF_RETAIN, CONF_SPEED, CONF_THEN, CONF_TOPIC, CONF_TRANSITION_LENGTH, CONF_TRIGGER_ID, \
CONF_TRIGGER_ID, CONF_WHITE CONF_WHITE
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, \ from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, add_job, \
bool_, esphomelib_ns, float_, get_variable, process_lambda, std_string, templatable, uint32, \ bool_, esphomelib_ns, float_, get_variable, process_lambda, std_string, templatable, uint32, \
uint8, add_job uint8
CONF_MQTT_PUBLISH = 'mqtt.publish' CONF_MQTT_PUBLISH = 'mqtt.publish'
CONF_LIGHT_TOGGLE = 'light.toggle' CONF_LIGHT_TOGGLE = 'light.toggle'
@ -26,11 +27,37 @@ CONF_COVER_STOP = 'cover.stop'
CONF_FAN_TOGGLE = 'fan.toggle' CONF_FAN_TOGGLE = 'fan.toggle'
CONF_FAN_TURN_OFF = 'fan.turn_off' CONF_FAN_TURN_OFF = 'fan.turn_off'
CONF_FAN_TURN_ON = 'fan.turn_on' 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):
validator = vol.All(*validators)
def validate(value):
if isinstance(value, dict):
return validator(value)
return validator({CONF_ID: value})
return validate
def validate_recursive_condition(value):
return CONDITIONS_SCHEMA(value)
def validate_recursive_action(value):
return ACTIONS_SCHEMA(value)
ACTION_KEYS = [CONF_DELAY, CONF_MQTT_PUBLISH, CONF_LIGHT_TOGGLE, CONF_LIGHT_TURN_OFF, ACTION_KEYS = [CONF_DELAY, CONF_MQTT_PUBLISH, CONF_LIGHT_TOGGLE, CONF_LIGHT_TURN_OFF,
CONF_LIGHT_TURN_ON, CONF_SWITCH_TOGGLE, CONF_SWITCH_TURN_OFF, CONF_SWITCH_TURN_ON, 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_LAMBDA, CONF_COVER_OPEN, CONF_COVER_CLOSE, CONF_COVER_STOP, CONF_FAN_TOGGLE,
CONF_FAN_TURN_OFF, CONF_FAN_TURN_ON] 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({ ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
cv.GenerateID(CONF_ACTION_ID): cv.declare_variable_id(None), cv.GenerateID(CONF_ACTION_ID): cv.declare_variable_id(None),
@ -41,15 +68,15 @@ ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos), vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos),
vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean), vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean),
}), }),
vol.Optional(CONF_LIGHT_TOGGLE): vol.Schema({ vol.Optional(CONF_LIGHT_TOGGLE): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds), vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
}), }),
vol.Optional(CONF_LIGHT_TURN_OFF): vol.Schema({ vol.Optional(CONF_LIGHT_TURN_OFF): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds), vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
}), }),
vol.Optional(CONF_LIGHT_TURN_ON): vol.Schema({ vol.Optional(CONF_LIGHT_TURN_ON): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'): vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'):
cv.templatable(cv.positive_time_period_milliseconds), cv.templatable(cv.positive_time_period_milliseconds),
@ -62,60 +89,75 @@ ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
vol.Optional(CONF_WHITE): cv.templatable(cv.percentage), vol.Optional(CONF_WHITE): cv.templatable(cv.percentage),
vol.Optional(CONF_EFFECT): cv.templatable(cv.string), vol.Optional(CONF_EFFECT): cv.templatable(cv.string),
}), }),
vol.Optional(CONF_SWITCH_TOGGLE): vol.Schema({ vol.Optional(CONF_SWITCH_TOGGLE): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_SWITCH_TURN_OFF): vol.Schema({ vol.Optional(CONF_SWITCH_TURN_OFF): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_SWITCH_TURN_ON): vol.Schema({ vol.Optional(CONF_SWITCH_TURN_ON): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_COVER_OPEN): vol.Schema({ vol.Optional(CONF_COVER_OPEN): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_COVER_CLOSE): vol.Schema({ vol.Optional(CONF_COVER_CLOSE): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_COVER_STOP): vol.Schema({ vol.Optional(CONF_COVER_STOP): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_COVER_OPEN): vol.Schema({ vol.Optional(CONF_COVER_OPEN): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_COVER_CLOSE): vol.Schema({ vol.Optional(CONF_COVER_CLOSE): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_COVER_STOP): vol.Schema({ vol.Optional(CONF_COVER_STOP): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_FAN_TOGGLE): vol.Schema({ vol.Optional(CONF_FAN_TOGGLE): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_FAN_TURN_OFF): vol.Schema({ vol.Optional(CONF_FAN_TURN_OFF): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
}), }),
vol.Optional(CONF_FAN_TURN_ON): vol.Schema({ vol.Optional(CONF_FAN_TURN_ON): maybe_simple_id({
vol.Required(CONF_ID): cv.use_variable_id(None), vol.Required(CONF_ID): cv.use_variable_id(None),
vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean), vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
vol.Optional(CONF_SPEED): cv.templatable(fan.validate_fan_speed), 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.zero_to_one_float,
},
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_, vol.Optional(CONF_LAMBDA): cv.lambda_,
}, cv.has_exactly_one_key(*ACTION_KEYS))]) }, cv.has_exactly_one_key(*ACTION_KEYS))])
# pylint: disable=invalid-name # pylint: disable=invalid-name
DelayAction = esphomelib_ns.DelayAction DelayAction = esphomelib_ns.DelayAction
LambdaAction = esphomelib_ns.LambdaAction LambdaAction = esphomelib_ns.LambdaAction
IfAction = esphomelib_ns.IfAction
Automation = esphomelib_ns.Automation Automation = esphomelib_ns.Automation
CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [cv.templatable({
def validate_recursive_condition(value):
return CONDITIONS_SCHEMA(value)
CONDITION_KEYS = [CONF_AND, CONF_OR, CONF_RANGE, CONF_LAMBDA]
CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(None), cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(None),
vol.Optional(CONF_AND): validate_recursive_condition, vol.Optional(CONF_AND): validate_recursive_condition,
vol.Optional(CONF_OR): validate_recursive_condition, vol.Optional(CONF_OR): validate_recursive_condition,
@ -124,7 +166,7 @@ CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
vol.Optional(CONF_BELOW): vol.Coerce(float), vol.Optional(CONF_BELOW): vol.Coerce(float),
}), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)), }), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)),
vol.Optional(CONF_LAMBDA): cv.lambda_, vol.Optional(CONF_LAMBDA): cv.lambda_,
}), cv.has_exactly_one_key(*CONDITION_KEYS)]) })])
# pylint: disable=invalid-name # pylint: disable=invalid-name
AndCondition = esphomelib_ns.AndCondition AndCondition = esphomelib_ns.AndCondition
@ -158,7 +200,12 @@ AUTOMATION_SCHEMA = vol.Schema({
def build_condition(config, arg_type): def build_condition(config, arg_type):
template_arg = TemplateArguments(arg_type) template_arg = TemplateArguments(arg_type)
if CONF_AND in config: if isinstance(config, core.Lambda):
lambda_ = None
for lambda_ in process_lambda(config, [(arg_type, 'x')]):
yield
yield LambdaCondition.new(template_arg, lambda_)
elif CONF_AND in config:
yield AndCondition.new(template_arg, build_conditions(config[CONF_AND], template_arg)) yield AndCondition.new(template_arg, build_conditions(config[CONF_AND], template_arg))
elif CONF_OR in config: elif CONF_OR in config:
yield OrCondition.new(template_arg, build_conditions(config[CONF_OR], template_arg)) yield OrCondition.new(template_arg, build_conditions(config[CONF_OR], template_arg))
@ -197,201 +244,240 @@ def build_conditions(config, arg_type):
yield ArrayInitializer(*conditions) yield ArrayInitializer(*conditions)
def build_action(config, arg_type): def build_action(full_config, arg_type):
from esphomeyaml.components import light, mqtt, switch from esphomeyaml.components import light, mqtt, switch
template_arg = TemplateArguments(arg_type) template_arg = TemplateArguments(arg_type)
# Keep pylint from freaking out # Keep pylint from freaking out
var = None var = None
if CONF_DELAY in config: action_id = full_config[CONF_ACTION_ID]
key, config = next((k, v) for k, v in full_config.items() if k in ACTION_KEYS)
if key == CONF_DELAY:
rhs = App.register_component(DelayAction.new(template_arg)) rhs = App.register_component(DelayAction.new(template_arg))
type = DelayAction.template(template_arg) type = DelayAction.template(template_arg)
action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) action = Pvariable(action_id, rhs, type=type)
template_ = None template_ = None
for template_ in templatable(config[CONF_DELAY], arg_type, uint32): for template_ in templatable(config, arg_type, uint32):
yield yield
add(action.set_delay(template_)) add(action.set_delay(template_))
yield action yield action
elif CONF_LAMBDA in config: elif key == CONF_LAMBDA:
lambda_ = None lambda_ = None
for lambda_ in process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')]): for lambda_ in process_lambda(config, [(arg_type, 'x')]):
yield None yield None
rhs = LambdaAction.new(template_arg, lambda_) rhs = LambdaAction.new(template_arg, lambda_)
type = LambdaAction.template(template_arg) type = LambdaAction.template(template_arg)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_MQTT_PUBLISH in config: elif key == CONF_MQTT_PUBLISH:
conf = config[CONF_MQTT_PUBLISH]
rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg) rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg)
type = mqtt.MQTTPublishAction.template(template_arg) type = mqtt.MQTTPublishAction.template(template_arg)
action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) action = Pvariable(action_id, rhs, type=type)
template_ = None template_ = None
for template_ in templatable(conf[CONF_TOPIC], arg_type, std_string): for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
yield None yield None
add(action.set_topic(template_)) add(action.set_topic(template_))
template_ = None template_ = None
for template_ in templatable(conf[CONF_PAYLOAD], arg_type, std_string): for template_ in templatable(config[CONF_PAYLOAD], arg_type, std_string):
yield None yield None
add(action.set_payload(template_)) add(action.set_payload(template_))
if CONF_QOS in conf: if CONF_QOS in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_QOS], arg_type, uint8): for template_ in templatable(config[CONF_QOS], arg_type, uint8):
yield yield
add(action.set_qos(template_)) add(action.set_qos(template_))
if CONF_RETAIN in conf: if CONF_RETAIN in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_RETAIN], arg_type, bool_): for template_ in templatable(config[CONF_RETAIN], arg_type, bool_):
yield None yield None
add(action.set_retain(template_)) add(action.set_retain(template_))
yield action yield action
elif CONF_LIGHT_TOGGLE in config: elif key == CONF_LIGHT_TOGGLE:
conf = config[CONF_LIGHT_TOGGLE] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_toggle_action(template_arg) rhs = var.make_toggle_action(template_arg)
type = light.ToggleAction.template(template_arg) type = light.ToggleAction.template(template_arg)
action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) action = Pvariable(action_id, rhs, type=type)
if CONF_TRANSITION_LENGTH in conf: if CONF_TRANSITION_LENGTH in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32): for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
yield None yield None
add(action.set_transition_length(template_)) add(action.set_transition_length(template_))
yield action yield action
elif CONF_LIGHT_TURN_OFF in config: elif key == CONF_LIGHT_TURN_OFF:
conf = config[CONF_LIGHT_TURN_OFF] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_turn_off_action(template_arg) rhs = var.make_turn_off_action(template_arg)
type = light.TurnOffAction.template(template_arg) type = light.TurnOffAction.template(template_arg)
action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) action = Pvariable(action_id, rhs, type=type)
if CONF_TRANSITION_LENGTH in conf: if CONF_TRANSITION_LENGTH in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32): for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
yield None yield None
add(action.set_transition_length(template_)) add(action.set_transition_length(template_))
yield action yield action
elif CONF_LIGHT_TURN_ON in config: elif key == CONF_LIGHT_TURN_ON:
conf = config[CONF_LIGHT_TURN_ON] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_turn_on_action(template_arg) rhs = var.make_turn_on_action(template_arg)
type = light.TurnOnAction.template(template_arg) type = light.TurnOnAction.template(template_arg)
action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) action = Pvariable(action_id, rhs, type=type)
if CONF_TRANSITION_LENGTH in conf: if CONF_TRANSITION_LENGTH in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32): for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
yield None yield None
add(action.set_transition_length(template_)) add(action.set_transition_length(template_))
if CONF_FLASH_LENGTH in conf: if CONF_FLASH_LENGTH in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_FLASH_LENGTH], arg_type, uint32): for template_ in templatable(config[CONF_FLASH_LENGTH], arg_type, uint32):
yield None yield None
add(action.set_flash_length(template_)) add(action.set_flash_length(template_))
if CONF_BRIGHTNESS in conf: if CONF_BRIGHTNESS in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_BRIGHTNESS], arg_type, float_): for template_ in templatable(config[CONF_BRIGHTNESS], arg_type, float_):
yield None yield None
add(action.set_brightness(template_)) add(action.set_brightness(template_))
if CONF_RED in conf: if CONF_RED in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_RED], arg_type, float_): for template_ in templatable(config[CONF_RED], arg_type, float_):
yield None yield None
add(action.set_red(template_)) add(action.set_red(template_))
if CONF_GREEN in conf: if CONF_GREEN in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_GREEN], arg_type, float_): for template_ in templatable(config[CONF_GREEN], arg_type, float_):
yield None yield None
add(action.set_green(template_)) add(action.set_green(template_))
if CONF_BLUE in conf: if CONF_BLUE in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_BLUE], arg_type, float_): for template_ in templatable(config[CONF_BLUE], arg_type, float_):
yield None yield None
add(action.set_blue(template_)) add(action.set_blue(template_))
if CONF_WHITE in conf: if CONF_WHITE in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_WHITE], arg_type, float_): for template_ in templatable(config[CONF_WHITE], arg_type, float_):
yield None yield None
add(action.set_white(template_)) add(action.set_white(template_))
if CONF_EFFECT in conf: if CONF_EFFECT in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_EFFECT], arg_type, std_string): for template_ in templatable(config[CONF_EFFECT], arg_type, std_string):
yield None yield None
add(action.set_effect(template_)) add(action.set_effect(template_))
yield action yield action
elif CONF_SWITCH_TOGGLE in config: elif key == CONF_SWITCH_TOGGLE:
conf = config[CONF_SWITCH_TOGGLE] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_toggle_action(template_arg) rhs = var.make_toggle_action(template_arg)
type = switch.ToggleAction.template(arg_type) type = switch.ToggleAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_SWITCH_TURN_OFF in config: elif key == CONF_SWITCH_TURN_OFF:
conf = config[CONF_SWITCH_TURN_OFF] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_turn_off_action(template_arg) rhs = var.make_turn_off_action(template_arg)
type = switch.TurnOffAction.template(arg_type) type = switch.TurnOffAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_SWITCH_TURN_ON in config: elif key == CONF_SWITCH_TURN_ON:
conf = config[CONF_SWITCH_TURN_ON] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_turn_on_action(template_arg) rhs = var.make_turn_on_action(template_arg)
type = switch.TurnOnAction.template(arg_type) type = switch.TurnOnAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_COVER_OPEN in config: elif key == CONF_COVER_OPEN:
conf = config[CONF_COVER_OPEN] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_open_action(template_arg) rhs = var.make_open_action(template_arg)
type = cover.OpenAction.template(arg_type) type = cover.OpenAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_COVER_CLOSE in config: elif key == CONF_COVER_CLOSE:
conf = config[CONF_COVER_CLOSE] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_close_action(template_arg) rhs = var.make_close_action(template_arg)
type = cover.CloseAction.template(arg_type) type = cover.CloseAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_COVER_STOP in config: elif key == CONF_COVER_STOP:
conf = config[CONF_COVER_STOP] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_stop_action(template_arg) rhs = var.make_stop_action(template_arg)
type = cover.StopAction.template(arg_type) type = cover.StopAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_FAN_TOGGLE in config: elif key == CONF_FAN_TOGGLE:
conf = config[CONF_FAN_TOGGLE] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_toggle_action(template_arg) rhs = var.make_toggle_action(template_arg)
type = fan.ToggleAction.template(arg_type) type = fan.ToggleAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_FAN_TURN_OFF in config: elif key == CONF_FAN_TURN_OFF:
conf = config[CONF_FAN_TURN_OFF] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_turn_off_action(template_arg) rhs = var.make_turn_off_action(template_arg)
type = fan.TurnOffAction.template(arg_type) type = fan.TurnOffAction.template(arg_type)
yield Pvariable(config[CONF_ACTION_ID], rhs, type=type) yield Pvariable(action_id, rhs, type=type)
elif CONF_FAN_TURN_ON in config: elif key == CONF_FAN_TURN_ON:
conf = config[CONF_FAN_TURN_ON] for var in get_variable(config[CONF_ID]):
for var in get_variable(conf[CONF_ID]):
yield None yield None
rhs = var.make_turn_on_action(template_arg) rhs = var.make_turn_on_action(template_arg)
type = fan.TurnOnAction.template(arg_type) type = fan.TurnOnAction.template(arg_type)
action = Pvariable(config[CONF_ACTION_ID], rhs, type=type) action = Pvariable(action_id, rhs, type=type)
if CONF_OSCILLATING in config: if CONF_OSCILLATING in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_OSCILLATING], arg_type, bool_): for template_ in templatable(config[CONF_OSCILLATING], arg_type, bool_):
yield None yield None
add(action.set_oscillating(template_)) add(action.set_oscillating(template_))
if CONF_SPEED in config: if CONF_SPEED in config:
template_ = None template_ = None
for template_ in templatable(conf[CONF_SPEED], arg_type, fan.FanSpeed): for template_ in templatable(config[CONF_SPEED], arg_type, fan.FanSpeed):
yield None yield None
add(action.set_speed(template_)) add(action.set_speed(template_))
yield action 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)
template_ = None
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: else:
raise ESPHomeYAMLError(u"Unsupported action {}".format(config)) raise ESPHomeYAMLError(u"Unsupported action {}".format(config))

View File

@ -2,16 +2,13 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor from esphomeyaml.components import binary_sensor
from esphomeyaml.components.esp32_ble_tracker import ESP32BLETracker from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32 make_address_array
from esphomeyaml.core import HexInt from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
from esphomeyaml.helpers import ArrayInitializer, get_variable from esphomeyaml.helpers import get_variable
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['esp32_ble_tracker'] DEPENDENCIES = ['esp32_ble_tracker']
CONF_ESP32_BLE_ID = 'esp32_ble_id'
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
vol.Required(CONF_MAC_ADDRESS): cv.mac_address, vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker) cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker)
@ -22,9 +19,5 @@ def to_code(config):
hub = None hub = None
for hub in get_variable(config[CONF_ESP32_BLE_ID]): for hub in get_variable(config[CONF_ESP32_BLE_ID]):
yield yield
addr = [HexInt(i) for i in config[CONF_MAC_ADDRESS].parts] rhs = hub.make_presence_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
rhs = hub.make_device(config[CONF_NAME], ArrayInitializer(*addr, multiline=False))
binary_sensor.register_binary_sensor(rhs, config) binary_sensor.register_binary_sensor(rhs, config)
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'

View File

@ -0,0 +1,42 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.pn532 import PN532Component
from esphomeyaml.const import CONF_NAME, CONF_UID
from esphomeyaml.core import HexInt
from esphomeyaml.helpers import ArrayInitializer, get_variable
DEPENDENCIES = ['pn532']
CONF_PN532_ID = 'pn532_id'
def validate_uid(value):
value = cv.string_strict(value)
for x in value.split('-'):
if len(x) != 2:
raise vol.Invalid("Each part (separated by '-') of the UID must be two characters "
"long.")
try:
x = int(x, 16)
except ValueError:
raise vol.Invalid("Valid characters for parts of a UID are 0123456789ABCDEF.")
if x < 0 or x > 255:
raise vol.Invalid("Valid values for UID parts (separated by '-') are 00 to FF")
return value
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
vol.Required(CONF_UID): validate_uid,
cv.GenerateID(CONF_PN532_ID): cv.use_variable_id(PN532Component)
}))
def to_code(config):
hub = None
for hub in get_variable(config[CONF_PN532_ID]):
yield
addr = [HexInt(int(x, 16)) for x in config[CONF_UID].split('-')]
rhs = hub.make_tag(config[CONF_NAME], ArrayInitializer(*addr, multiline=False))
binary_sensor.register_binary_sensor(rhs, config)

View File

@ -0,0 +1,24 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.rdm6300 import RDM6300Component
from esphomeyaml.const import CONF_NAME, CONF_UID
from esphomeyaml.helpers import get_variable
DEPENDENCIES = ['rdm6300']
CONF_RDM6300_ID = 'rdm6300_id'
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
vol.Required(CONF_UID): cv.uint32_t,
cv.GenerateID(CONF_RDM6300_ID): cv.use_variable_id(RDM6300Component)
}))
def to_code(config):
hub = None
for hub in get_variable(config[CONF_RDM6300_ID]):
yield
rhs = hub.make_tag(config[CONF_NAME], config[CONF_UID])
binary_sensor.register_binary_sensor(rhs, config)

View File

@ -3,13 +3,20 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor from esphomeyaml.components import binary_sensor
from esphomeyaml.components.remote_receiver import RemoteReceiverComponent, remote_ns from esphomeyaml.components.remote_receiver import RemoteReceiverComponent, remote_ns
from esphomeyaml.const import CONF_ADDRESS, CONF_COMMAND, CONF_DATA, \ from esphomeyaml.components.remote_transmitter import RC_SWITCH_RAW_SCHEMA, \
CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_RAW, CONF_SONY RC_SWITCH_TYPE_A_SCHEMA, RC_SWITCH_TYPE_B_SCHEMA, RC_SWITCH_TYPE_C_SCHEMA, \
RC_SWITCH_TYPE_D_SCHEMA, binary_code, build_rc_switch_protocol
from esphomeyaml.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAND, CONF_DATA, \
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \
CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \
CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SONY, CONF_STATE
from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable
DEPENDENCIES = ['remote_receiver'] DEPENDENCIES = ['remote_receiver']
IR_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW] REMOTE_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW, CONF_RC_SWITCH_RAW,
CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C,
CONF_RC_SWITCH_TYPE_D]
CONF_REMOTE_RECEIVER_ID = 'remote_receiver_id' CONF_REMOTE_RECEIVER_ID = 'remote_receiver_id'
CONF_RECEIVER_ID = 'receiver_id' CONF_RECEIVER_ID = 'receiver_id'
@ -20,6 +27,11 @@ NECReceiver = remote_ns.NECReceiver
PanasonicReceiver = remote_ns.PanasonicReceiver PanasonicReceiver = remote_ns.PanasonicReceiver
RawReceiver = remote_ns.RawReceiver RawReceiver = remote_ns.RawReceiver
SonyReceiver = remote_ns.SonyReceiver SonyReceiver = remote_ns.SonyReceiver
RCSwitchRawReceiver = remote_ns.RCSwitchRawReceiver
RCSwitchTypeAReceiver = remote_ns.RCSwitchTypeAReceiver
RCSwitchTypeBReceiver = remote_ns.RCSwitchTypeBReceiver
RCSwitchTypeCReceiver = remote_ns.RCSwitchTypeCReceiver
RCSwitchTypeDReceiver = remote_ns.RCSwitchTypeDReceiver
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_LG): vol.Schema({ vol.Optional(CONF_LG): vol.Schema({
@ -39,29 +51,54 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
vol.Required(CONF_COMMAND): cv.hex_uint32_t, vol.Required(CONF_COMMAND): cv.hex_uint32_t,
}), }),
vol.Optional(CONF_RAW): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], vol.Optional(CONF_RAW): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_C): RC_SWITCH_TYPE_C_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_D): RC_SWITCH_TYPE_D_SCHEMA,
cv.GenerateID(CONF_REMOTE_RECEIVER_ID): cv.use_variable_id(RemoteReceiverComponent), cv.GenerateID(CONF_REMOTE_RECEIVER_ID): cv.use_variable_id(RemoteReceiverComponent),
cv.GenerateID(CONF_RECEIVER_ID): cv.declare_variable_id(RemoteReceiver), cv.GenerateID(CONF_RECEIVER_ID): cv.declare_variable_id(RemoteReceiver),
}), cv.has_exactly_one_key(*IR_KEYS)) }), cv.has_exactly_one_key(*REMOTE_KEYS))
def receiver_base(config): def receiver_base(full_config):
if CONF_LG in config: name = full_config[CONF_NAME]
conf = config[CONF_LG] key, config = next((k, v) for k, v in full_config.items() if k in REMOTE_KEYS)
return LGReceiver.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS]) if key == CONF_LG:
elif CONF_NEC in config: return LGReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
conf = config[CONF_NEC] elif key == CONF_NEC:
return NECReceiver.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND]) return NECReceiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
elif CONF_PANASONIC in config: elif key == CONF_PANASONIC:
conf = config[CONF_PANASONIC] return PanasonicReceiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
return PanasonicReceiver.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND]) elif key == CONF_SONY:
elif CONF_SONY in config: return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
conf = config[CONF_SONY] elif key == CONF_RAW:
return SonyReceiver.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS])
elif CONF_RAW in config:
data = ArrayInitializer(*config[CONF_RAW], multiline=False) data = ArrayInitializer(*config[CONF_RAW], multiline=False)
return RawReceiver.new(config[CONF_NAME], data) return RawReceiver.new(name, data)
elif key == CONF_RC_SWITCH_RAW:
return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
elif key == CONF_RC_SWITCH_TYPE_A:
return RCSwitchTypeAReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_GROUP]),
binary_code(config[CONF_DEVICE]),
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_B:
return RCSwitchTypeBReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
config[CONF_ADDRESS], config[CONF_CHANNEL],
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_C:
return RCSwitchTypeCReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
ord(config[CONF_FAMILY][0]) - ord('a'),
config[CONF_GROUP], config[CONF_DEVICE],
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_D:
return RCSwitchTypeDReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
ord(config[CONF_GROUP][0]) - ord('a'),
config[CONF_DEVICE], config[CONF_STATE])
else: else:
raise ValueError("Unknown receiver type {}".format(config)) raise NotImplementedError("Unknown receiver type {}".format(config))
def to_code(config): def to_code(config):

View File

@ -3,7 +3,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor from esphomeyaml.components import binary_sensor
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME
from esphomeyaml.helpers import App, Application, process_lambda, variable, optional, bool_ from esphomeyaml.helpers import App, Application, process_lambda, variable, optional, bool_, add
MakeTemplateBinarySensor = Application.MakeTemplateBinarySensor MakeTemplateBinarySensor = Application.MakeTemplateBinarySensor
@ -14,13 +14,15 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
def to_code(config): def to_code(config):
rhs = App.make_template_binary_sensor(config[CONF_NAME])
make = variable(config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(make.Ptemplate_, make.Pmqtt, config)
template_ = None template_ = None
for template_ in process_lambda(config[CONF_LAMBDA], [], for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(bool_)): return_type=optional.template(bool_)):
yield yield
rhs = App.make_template_binary_sensor(config[CONF_NAME], template_) add(make.Ptemplate_.set_template(template_))
make = variable(config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR' BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'

View File

@ -23,6 +23,8 @@ def to_code(config):
rhs = App.make_template_cover(config[CONF_NAME]) rhs = App.make_template_cover(config[CONF_NAME])
make = variable(config[CONF_MAKE_ID], rhs) make = variable(config[CONF_MAKE_ID], rhs)
cover.setup_cover(make.Ptemplate_, make.Pmqtt, config)
if CONF_LAMBDA in config: if CONF_LAMBDA in config:
template_ = None template_ = None
for template_ in process_lambda(config[CONF_LAMBDA], [], for template_ in process_lambda(config[CONF_LAMBDA], [],
@ -41,7 +43,5 @@ def to_code(config):
if CONF_OPTIMISTIC in config: if CONF_OPTIMISTIC in config:
add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC])) add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC]))
cover.setup_cover(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_COVER' BUILD_FLAGS = '-DUSE_TEMPLATE_COVER'

View File

@ -15,6 +15,8 @@ def validate_pin_number(value):
DeepSleepComponent = esphomelib_ns.DeepSleepComponent DeepSleepComponent = esphomelib_ns.DeepSleepComponent
EnterDeepSleepAction = esphomelib_ns.EnterDeepSleepAction
PreventDeepSleepAction = esphomelib_ns.PreventDeepSleepAction
WAKEUP_PIN_MODES = { WAKEUP_PIN_MODES = {
'IGNORE': esphomelib_ns.WAKEUP_PIN_MODE_IGNORE, 'IGNORE': esphomelib_ns.WAKEUP_PIN_MODE_IGNORE,

View File

@ -2,10 +2,12 @@ import voluptuous as vol
from esphomeyaml import config_validation as cv from esphomeyaml import config_validation as cv
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32 from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns from esphomeyaml.core import HexInt
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, ArrayInitializer
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
CONF_ESP32_BLE_ID = 'esp32_ble_id'
ESP32BLETracker = esphomelib_ns.ESP32BLETracker ESP32BLETracker = esphomelib_ns.ESP32BLETracker
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
@ -14,6 +16,11 @@ CONFIG_SCHEMA = vol.Schema({
}) })
def make_address_array(address):
addr = [HexInt(i) for i in address.parts]
return ArrayInitializer(*addr, multiline=False)
def to_code(config): def to_code(config):
rhs = App.make_esp32_ble_tracker() rhs = App.make_esp32_ble_tracker()
ble = Pvariable(config[CONF_ID], rhs) ble = Pvariable(config[CONF_ID], rhs)

View File

@ -1,7 +1,14 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \ from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLORS, \
CONF_MQTT_ID, CONF_INTERNAL CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECTS, CONF_EFFECT_ID, \
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component CONF_GAMMA_CORRECT, \
CONF_GREEN, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, CONF_NUM_LEDS, \
CONF_RANDOM, CONF_RED, CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, CONF_UPDATE_INTERVAL, \
CONF_WHITE, CONF_WIDTH
from esphomeyaml.helpers import Application, ArrayInitializer, Pvariable, RawExpression, \
StructInitializer, add, add_job, esphomelib_ns, process_lambda, setup_mqtt_component
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
@ -9,11 +16,174 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
light_ns = esphomelib_ns.namespace('light') light_ns = esphomelib_ns.namespace('light')
LightState = light_ns.LightState LightState = light_ns.LightState
LightColorValues = light_ns.LightColorValues
MQTTJSONLightComponent = light_ns.MQTTJSONLightComponent MQTTJSONLightComponent = light_ns.MQTTJSONLightComponent
ToggleAction = light_ns.ToggleAction ToggleAction = light_ns.ToggleAction
TurnOffAction = light_ns.TurnOffAction TurnOffAction = light_ns.TurnOffAction
TurnOnAction = light_ns.TurnOnAction TurnOnAction = light_ns.TurnOnAction
MakeLight = Application.MakeLight MakeLight = Application.MakeLight
RandomLightEffect = light_ns.RandomLightEffect
LambdaLightEffect = light_ns.LambdaLightEffect
StrobeLightEffect = light_ns.StrobeLightEffect
StrobeLightEffectColor = light_ns.StrobeLightEffectColor
FlickerLightEffect = light_ns.FlickerLightEffect
FastLEDLambdaLightEffect = light_ns.FastLEDLambdaLightEffect
FastLEDRainbowLightEffect = light_ns.FastLEDRainbowLightEffect
FastLEDColorWipeEffect = light_ns.FastLEDColorWipeEffect
FastLEDColorWipeEffectColor = light_ns.FastLEDColorWipeEffectColor
FastLEDScanEffect = light_ns.FastLEDScanEffect
FastLEDScanEffectColor = light_ns.FastLEDScanEffectColor
FastLEDTwinkleEffect = light_ns.FastLEDTwinkleEffect
FastLEDRandomTwinkleEffect = light_ns.FastLEDRandomTwinkleEffect
FastLEDFireworksEffect = light_ns.FastLEDFireworksEffect
FastLEDFlickerEffect = light_ns.FastLEDFlickerEffect
FastLEDLightOutputComponent = light_ns.FastLEDLightOutputComponent
CONF_STROBE = 'strobe'
CONF_FLICKER = 'flicker'
CONF_FASTLED_LAMBDA = 'fastled_lambda'
CONF_FASTLED_RAINBOW = 'fastled_rainbow'
CONF_FASTLED_COLOR_WIPE = 'fastled_color_wipe'
CONF_FASTLED_SCAN = 'fastled_scan'
CONF_FASTLED_TWINKLE = 'fastled_twinkle'
CONF_FASTLED_RANDOM_TWINKLE = 'fastled_random_twinkle'
CONF_FASTLED_FIREWORKS = 'fastled_fireworks'
CONF_FASTLED_FLICKER = 'fastled_flicker'
CONF_ADD_LED_INTERVAL = 'add_led_interval'
CONF_REVERSE = 'reverse'
CONF_MOVE_INTERVAL = 'move_interval'
CONF_TWINKLE_PROBABILITY = 'twinkle_probability'
CONF_PROGRESS_INTERVAL = 'progress_interval'
CONF_SPARK_PROBABILITY = 'spark_probability'
CONF_USE_RANDOM_COLOR = 'use_random_color'
CONF_FADE_OUT_RATE = 'fade_out_rate'
CONF_INTENSITY = 'intensity'
BINARY_EFFECTS = [CONF_LAMBDA, CONF_STROBE]
MONOCHROMATIC_EFFECTS = BINARY_EFFECTS + [CONF_FLICKER]
RGB_EFFECTS = MONOCHROMATIC_EFFECTS + [CONF_RANDOM]
FASTLED_EFFECTS = RGB_EFFECTS + [CONF_FASTLED_LAMBDA, CONF_FASTLED_RAINBOW, CONF_FASTLED_COLOR_WIPE,
CONF_FASTLED_SCAN, CONF_FASTLED_TWINKLE,
CONF_FASTLED_RANDOM_TWINKLE, CONF_FASTLED_FIREWORKS,
CONF_FASTLED_FLICKER]
EFFECTS_SCHEMA = vol.Schema({
vol.Optional(CONF_LAMBDA): vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_LAMBDA): cv.lambda_,
}),
vol.Optional(CONF_RANDOM): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(RandomLightEffect),
vol.Optional(CONF_NAME, default="Random"): cv.string,
vol.Optional(CONF_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}),
vol.Optional(CONF_STROBE): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(StrobeLightEffect),
vol.Optional(CONF_NAME, default="Strobe"): cv.string,
vol.Optional(CONF_COLORS): vol.All(cv.ensure_list, [vol.All(vol.Schema({
vol.Optional(CONF_STATE, default=True): cv.boolean,
vol.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
vol.Optional(CONF_RED, default=1.0): cv.percentage,
vol.Optional(CONF_GREEN, default=1.0): cv.percentage,
vol.Optional(CONF_BLUE, default=1.0): cv.percentage,
vol.Optional(CONF_WHITE, default=1.0): cv.percentage,
vol.Required(CONF_DURATION): cv.positive_time_period_milliseconds,
}), cv.has_at_least_one_key(CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE,
CONF_WHITE))], vol.Length(min=2)),
}),
vol.Optional(CONF_FLICKER): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FlickerLightEffect),
vol.Optional(CONF_NAME, default="Flicker"): cv.string,
vol.Optional(CONF_ALPHA): cv.percentage,
vol.Optional(CONF_INTENSITY): cv.percentage,
}),
vol.Optional(CONF_FASTLED_LAMBDA): vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_LAMBDA): cv.lambda_,
}),
vol.Optional(CONF_FASTLED_RAINBOW): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDRainbowLightEffect),
vol.Optional(CONF_NAME, default="Rainbow"): cv.string,
vol.Optional(CONF_SPEED): cv.uint32_t,
vol.Optional(CONF_WIDTH): cv.uint32_t,
}),
vol.Optional(CONF_FASTLED_COLOR_WIPE): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDColorWipeEffect),
vol.Optional(CONF_NAME, default="Color Wipe"): cv.string,
vol.Optional(CONF_COLORS): vol.All(cv.ensure_list, [vol.Schema({
vol.Optional(CONF_RED, default=1.0): cv.percentage,
vol.Optional(CONF_GREEN, default=1.0): cv.percentage,
vol.Optional(CONF_BLUE, default=1.0): cv.percentage,
vol.Optional(CONF_RANDOM, default=False): cv.boolean,
vol.Required(CONF_NUM_LEDS): vol.All(cv.uint32_t, vol.Range(min=1)),
})]),
vol.Optional(CONF_ADD_LED_INTERVAL): cv.positive_time_period_milliseconds,
vol.Optional(CONF_REVERSE): cv.boolean,
}),
vol.Optional(CONF_FASTLED_SCAN): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDScanEffect),
vol.Optional(CONF_NAME, default="Scan"): cv.string,
vol.Optional(CONF_MOVE_INTERVAL): cv.positive_time_period_milliseconds,
}),
vol.Optional(CONF_FASTLED_TWINKLE): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDTwinkleEffect),
vol.Optional(CONF_NAME, default="Twinkle"): cv.string,
vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage,
vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds,
}),
vol.Optional(CONF_FASTLED_RANDOM_TWINKLE): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDRandomTwinkleEffect),
vol.Optional(CONF_NAME, default="Random Twinkle"): cv.string,
vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage,
vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds,
}),
vol.Optional(CONF_FASTLED_FIREWORKS): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDFireworksEffect),
vol.Optional(CONF_NAME, default="Fireworks"): cv.string,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
vol.Optional(CONF_SPARK_PROBABILITY): cv.percentage,
vol.Optional(CONF_USE_RANDOM_COLOR): cv.boolean,
vol.Optional(CONF_FADE_OUT_RATE): cv.uint8_t,
}),
vol.Optional(CONF_FASTLED_FLICKER): vol.Schema({
cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FastLEDFlickerEffect),
vol.Optional(CONF_NAME, default="FastLED Flicker"): cv.string,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
vol.Optional(CONF_INTENSITY): cv.percentage,
}),
})
def validate_effects(allowed_effects):
def validator(value):
value = cv.ensure_list(value)
names = set()
ret = []
for i, effect in enumerate(value):
if not isinstance(effect, dict):
raise vol.Invalid("Each effect must be a dictionary, not {}".format(type(value)))
if len(effect) > 1:
raise vol.Invalid("Each entry in the 'effects:' option must be a single effect.")
if not effect:
raise vol.Invalid("Found no effect for the {}th entry in 'effects:'!".format(i))
key = next(iter(effect.keys()))
if key not in allowed_effects:
raise vol.Invalid("The effect '{}' does not exist or is not allowed for this "
"light type".format(key))
effect[key] = effect[key] or {}
conf = EFFECTS_SCHEMA(effect)
name = conf[key][CONF_NAME]
if name in names:
raise vol.Invalid(u"Found the effect name '{}' twice. All effects must have "
u"unique names".format(name))
names.add(name)
ret.append(conf)
return ret
return validator
LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(LightState), cv.GenerateID(): cv.declare_variable_id(LightState),
@ -23,6 +193,124 @@ LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
LIGHT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(LIGHT_SCHEMA.schema) LIGHT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(LIGHT_SCHEMA.schema)
def build_effect(full_config):
key, config = next(iter(full_config.items()))
if key == CONF_LAMBDA:
lambda_ = None
for lambda_ in process_lambda(config[CONF_LAMBDA], []):
yield None
yield LambdaLightEffect.new(config[CONF_NAME], lambda_)
elif key == CONF_RANDOM:
rhs = RandomLightEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_TRANSITION_LENGTH in config:
add(effect.set_transition_length(config[CONF_TRANSITION_LENGTH]))
if CONF_UPDATE_INTERVAL in config:
add(effect.set_update_interval(config[CONF_UPDATE_INTERVAL]))
yield effect
elif key == CONF_STROBE:
rhs = StrobeLightEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
colors = []
for color in config.get(CONF_COLORS, []):
colors.append(StructInitializer(
StrobeLightEffectColor,
('color', LightColorValues(color[CONF_STATE], color[CONF_BRIGHTNESS],
color[CONF_RED], color[CONF_GREEN], color[CONF_BLUE],
color[CONF_WHITE])),
('duration', color[CONF_DURATION]),
))
if colors:
add(effect.set_colors(ArrayInitializer(*colors)))
yield effect
elif key == CONF_FLICKER:
rhs = FlickerLightEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_ALPHA in config:
add(effect.set_alpha(config[CONF_ALPHA]))
if CONF_INTENSITY in config:
add(effect.set_intensity(config[CONF_INTENSITY]))
yield effect
elif key == CONF_FASTLED_LAMBDA:
lambda_ = None
args = [(RawExpression('FastLEDLightOutputComponent &'), 'fastled')]
for lambda_ in process_lambda(config[CONF_LAMBDA], args):
yield None
yield FastLEDLambdaLightEffect.new(config[CONF_NAME], lambda_)
elif key == CONF_FASTLED_RAINBOW:
rhs = FastLEDRainbowLightEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_SPEED in config:
add(effect.set_speed(config[CONF_SPEED]))
if CONF_WIDTH in config:
add(effect.set_width(config[CONF_WIDTH]))
yield effect
elif key == CONF_FASTLED_COLOR_WIPE:
rhs = FastLEDColorWipeEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_ADD_LED_INTERVAL in config:
add(effect.set_add_led_interval(config[CONF_ADD_LED_INTERVAL]))
if CONF_REVERSE in config:
add(effect.set_reverse(config[CONF_REVERSE]))
colors = []
for color in config.get(CONF_COLORS, []):
colors.append(StructInitializer(
FastLEDColorWipeEffectColor,
('r', color[CONF_RED]),
('g', color[CONF_GREEN]),
('b', color[CONF_BLUE]),
('random', color[CONF_RANDOM]),
('num_leds', color[CONF_NUM_LEDS]),
))
if colors:
add(effect.set_colors(ArrayInitializer(*colors)))
yield effect
elif key == CONF_FASTLED_SCAN:
rhs = FastLEDScanEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_MOVE_INTERVAL in config:
add(effect.set_move_interval(config[CONF_MOVE_INTERVAL]))
yield effect
elif key == CONF_FASTLED_TWINKLE:
rhs = FastLEDTwinkleEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_TWINKLE_PROBABILITY in config:
add(effect.set_twinkle_probability(config[CONF_TWINKLE_PROBABILITY]))
if CONF_PROGRESS_INTERVAL in config:
add(effect.set_progress_interval(config[CONF_PROGRESS_INTERVAL]))
yield effect
elif key == CONF_FASTLED_RANDOM_TWINKLE:
rhs = FastLEDRandomTwinkleEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_TWINKLE_PROBABILITY in config:
add(effect.set_twinkle_probability(config[CONF_TWINKLE_PROBABILITY]))
if CONF_PROGRESS_INTERVAL in config:
add(effect.set_progress_interval(config[CONF_PROGRESS_INTERVAL]))
yield effect
elif key == CONF_FASTLED_FIREWORKS:
rhs = FastLEDFireworksEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_UPDATE_INTERVAL in config:
add(effect.set_update_interval(config[CONF_UPDATE_INTERVAL]))
if CONF_SPARK_PROBABILITY in config:
add(effect.set_spark_probability(config[CONF_SPARK_PROBABILITY]))
if CONF_USE_RANDOM_COLOR in config:
add(effect.set_spark_probability(config[CONF_USE_RANDOM_COLOR]))
if CONF_FADE_OUT_RATE in config:
add(effect.set_spark_probability(config[CONF_FADE_OUT_RATE]))
yield effect
elif key == CONF_FASTLED_FLICKER:
rhs = FastLEDFlickerEffect.new(config[CONF_NAME])
effect = Pvariable(config[CONF_EFFECT_ID], rhs)
if CONF_UPDATE_INTERVAL in config:
add(effect.set_update_interval(config[CONF_UPDATE_INTERVAL]))
if CONF_INTENSITY in config:
add(effect.set_intensity(config[CONF_INTENSITY]))
yield effect
else:
raise NotImplementedError("Effect {} not implemented".format(next(config.keys())))
def setup_light_core_(light_var, mqtt_var, config): def setup_light_core_(light_var, mqtt_var, config):
if CONF_INTERNAL in config: if CONF_INTERNAL in config:
add(light_var.set_internal(config[CONF_INTERNAL])) add(light_var.set_internal(config[CONF_INTERNAL]))
@ -30,6 +318,13 @@ def setup_light_core_(light_var, mqtt_var, config):
add(light_var.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH])) add(light_var.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH]))
if CONF_GAMMA_CORRECT in config: if CONF_GAMMA_CORRECT in config:
add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT])) add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
effects = []
for conf in config.get(CONF_EFFECTS, []):
for effect in build_effect(conf):
yield
effects.append(effect)
if effects:
add(light_var.add_effects(ArrayInitializer(*effects)))
setup_mqtt_component(mqtt_var, config) setup_mqtt_component(mqtt_var, config)
@ -37,7 +332,7 @@ def setup_light_core_(light_var, mqtt_var, config):
def setup_light(light_obj, mqtt_obj, config): def setup_light(light_obj, mqtt_obj, config):
light_var = Pvariable(config[CONF_ID], light_obj, has_side_effects=False) light_var = Pvariable(config[CONF_ID], light_obj, has_side_effects=False)
mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False) mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False)
setup_light_core_(light_var, mqtt_var, config) add_job(setup_light_core_, light_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_LIGHT' BUILD_FLAGS = '-DUSE_LIGHT'

View File

@ -2,12 +2,13 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import light from esphomeyaml.components import light
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT, CONF_EFFECTS
from esphomeyaml.helpers import App, get_variable, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight), cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
vol.Required(CONF_OUTPUT): cv.use_variable_id(None), vol.Required(CONF_OUTPUT): cv.use_variable_id(None),
vol.Optional(CONF_EFFECTS): light.validate_effects(light.BINARY_EFFECTS),
})) }))

View File

@ -6,7 +6,7 @@ from esphomeyaml.components import light
from esphomeyaml.components.power_supply import PowerSupplyComponent from esphomeyaml.components.power_supply import PowerSupplyComponent
from esphomeyaml.const import CONF_CHIPSET, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ from esphomeyaml.const import CONF_CHIPSET, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, \ CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, \
CONF_RGB_ORDER CONF_RGB_ORDER, CONF_EFFECTS
from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \ from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
get_variable, variable get_variable, variable
@ -68,6 +68,7 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent),
vol.Optional(CONF_EFFECTS): light.validate_effects(light.FASTLED_EFFECTS),
}), validate) }), validate)

View File

@ -6,7 +6,7 @@ from esphomeyaml.components import light
from esphomeyaml.components.power_supply import PowerSupplyComponent from esphomeyaml.components.power_supply import PowerSupplyComponent
from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, \ from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, \
CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, \
CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER, CONF_EFFECTS
from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \ from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
get_variable, variable get_variable, variable
@ -46,6 +46,7 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent), vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent),
vol.Optional(CONF_EFFECTS): light.validate_effects(light.FASTLED_EFFECTS),
})) }))

View File

@ -3,7 +3,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import light from esphomeyaml.components import light
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \ from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \
CONF_NAME, CONF_OUTPUT CONF_NAME, CONF_OUTPUT, CONF_EFFECTS
from esphomeyaml.helpers import App, get_variable, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
@ -11,6 +11,7 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
vol.Required(CONF_OUTPUT): cv.use_variable_id(None), vol.Required(CONF_OUTPUT): cv.use_variable_id(None),
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_EFFECTS): light.validate_effects(light.MONOCHROMATIC_EFFECTS),
})) }))

View File

@ -3,7 +3,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import light from esphomeyaml.components import light
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_EFFECTS
from esphomeyaml.helpers import App, get_variable, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
@ -13,6 +13,7 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
vol.Required(CONF_BLUE): cv.use_variable_id(None), vol.Required(CONF_BLUE): cv.use_variable_id(None),
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_EFFECTS): light.validate_effects(light.RGB_EFFECTS),
})) }))

View File

@ -3,7 +3,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import light from esphomeyaml.components import light
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \ from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE, CONF_EFFECTS
from esphomeyaml.helpers import App, get_variable, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
@ -14,6 +14,7 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
vol.Required(CONF_WHITE): cv.use_variable_id(None), vol.Required(CONF_WHITE): cv.use_variable_id(None),
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float, vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds, vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_EFFECTS): light.validate_effects(light.RGB_EFFECTS),
})) }))

View File

@ -23,6 +23,9 @@ FLOAT_OUTPUT_SCHEMA = BINARY_OUTPUT_SCHEMA.extend({
FLOAT_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FLOAT_OUTPUT_SCHEMA.schema) FLOAT_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FLOAT_OUTPUT_SCHEMA.schema)
output_ns = esphomelib_ns.namespace('output') output_ns = esphomelib_ns.namespace('output')
TurnOffAction = output_ns.TurnOffAction
TurnOnAction = output_ns.TurnOnAction
SetLevelAction = output_ns.SetLevelAction
def setup_output_platform_(obj, config, skip_power_supply=False): def setup_output_platform_(obj, config, skip_power_supply=False):

View File

@ -0,0 +1,34 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import pins
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.spi import SPIComponent
from esphomeyaml.const import CONF_CS, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Pvariable, get_variable, gpio_output_pin_expression
DEPENDENCIES = ['spi']
PN532Component = binary_sensor.binary_sensor_ns.PN532Component
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
cv.GenerateID(): cv.declare_variable_id(PN532Component),
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
vol.Required(CONF_CS): pins.gpio_output_pin_schema,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
})])
def to_code(config):
for conf in config:
spi = None
for spi in get_variable(conf[CONF_SPI_ID]):
yield
cs = None
for cs in gpio_output_pin_expression(conf[CONF_CS]):
yield
rhs = App.make_pn532_component(spi, cs, conf.get(CONF_UPDATE_INTERVAL))
Pvariable(conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_PN532'

View File

@ -0,0 +1,28 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.uart import UARTComponent
from esphomeyaml.const import CONF_ID, CONF_UART_ID
from esphomeyaml.helpers import App, Pvariable, get_variable
DEPENDENCIES = ['uart']
RDM6300Component = binary_sensor.binary_sensor_ns.RDM6300Component
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
cv.GenerateID(): cv.declare_variable_id(RDM6300Component),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
})])
def to_code(config):
for conf in config:
uart = None
for uart in get_variable(conf[CONF_UART_ID]):
yield
rhs = App.make_rdm6300_component(uart)
Pvariable(conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_RDM6300'

View File

@ -16,6 +16,7 @@ DUMPERS = {
'panasonic': remote_ns.PanasonicDumper, 'panasonic': remote_ns.PanasonicDumper,
'raw': remote_ns.RawDumper, 'raw': remote_ns.RawDumper,
'sony': remote_ns.SonyDumper, 'sony': remote_ns.SonyDumper,
'rc_switch': remote_ns.RCSwitchDumper,
} }
@ -23,7 +24,7 @@ def validate_dumpers_all(value):
if not isinstance(value, (str, unicode)): if not isinstance(value, (str, unicode)):
raise vol.Invalid("Not valid dumpers") raise vol.Invalid("Not valid dumpers")
if value.upper() == "ALL": if value.upper() == "ALL":
return list(DUMPERS) return list(sorted(list(DUMPERS)))
raise vol.Invalid("Not valid dumpers") raise vol.Invalid("Not valid dumpers")

View File

@ -2,13 +2,79 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN from esphomeyaml.components.switch.remote_transmitter import rc_switch_protocols, RCSwitchProtocol
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_DUTY_PERCENT, CONF_CHANNEL, CONF_CODE, \
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_ID, CONF_INVERTED, CONF_ONE, CONF_PIN, \
CONF_PROTOCOL, CONF_PULSE_LENGTH, CONF_STATE, CONF_SYNC, CONF_ZERO
from esphomeyaml.core import HexInt
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression
remote_ns = esphomelib_ns.namespace('remote') remote_ns = esphomelib_ns.namespace('remote')
RemoteTransmitterComponent = remote_ns.RemoteTransmitterComponent RemoteTransmitterComponent = remote_ns.RemoteTransmitterComponent
def validate_rc_switch_code(value):
if not isinstance(value, (str, unicode)):
raise vol.Invalid("All RCSwitch codes must be in quotes ('')")
for c in value:
if c not in ('0', '1'):
raise vol.Invalid(u"Invalid RCSwitch code character '{}'. Only '0' and '1' are allowed"
u"".format(c))
if len(value) > 32:
raise vol.Invalid("Maximum length for RCSwitch codes is 32, code '{}' has length {}"
"".format(value, len(value)))
if not value:
raise vol.Invalid("RCSwitch code must not be empty")
return value
RC_SWITCH_TIMING_SCHEMA = vol.All([cv.uint8_t], vol.Length(min=2, max=2))
RC_SWITCH_PROTOCOL_SCHEMA = vol.Any(
vol.All(vol.Coerce(int), vol.Range(min=1, max=7)),
vol.Schema({
vol.Required(CONF_PULSE_LENGTH): cv.uint32_t,
vol.Optional(CONF_SYNC, default=[1, 31]): RC_SWITCH_TIMING_SCHEMA,
vol.Optional(CONF_ZERO, default=[1, 3]): RC_SWITCH_TIMING_SCHEMA,
vol.Optional(CONF_ONE, default=[3, 1]): RC_SWITCH_TIMING_SCHEMA,
vol.Optional(CONF_INVERTED, default=False): cv.boolean,
})
)
RC_SWITCH_RAW_SCHEMA = vol.Schema({
vol.Required(CONF_CODE): validate_rc_switch_code,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
})
RC_SWITCH_TYPE_A_SCHEMA = vol.Schema({
vol.Required(CONF_GROUP): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)),
vol.Required(CONF_DEVICE): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)),
vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
})
RC_SWITCH_TYPE_B_SCHEMA = vol.Schema({
vol.Required(CONF_ADDRESS): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
vol.Required(CONF_CHANNEL): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
})
RC_SWITCH_TYPE_C_SCHEMA = vol.Schema({
vol.Required(CONF_FAMILY): vol.All(
cv.string, vol.Lower,
cv.one_of('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p')),
vol.Required(CONF_GROUP): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
vol.Required(CONF_DEVICE): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
})
RC_SWITCH_TYPE_D_SCHEMA = vol.Schema({
vol.Required(CONF_GROUP): vol.All(cv.string, vol.Lower, cv.one_of('a', 'b', 'c', 'd')),
vol.Required(CONF_DEVICE): vol.All(cv.uint8_t, vol.Range(min=1, max=3)),
vol.Required(CONF_STATE): cv.boolean,
vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
})
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
cv.GenerateID(): cv.declare_variable_id(RemoteTransmitterComponent), cv.GenerateID(): cv.declare_variable_id(RemoteTransmitterComponent),
vol.Required(CONF_PIN): pins.gpio_output_pin_schema, vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
@ -17,6 +83,24 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
})]) })])
def build_rc_switch_protocol(config):
if isinstance(config, int):
return rc_switch_protocols[config]
pl = config[CONF_PULSE_LENGTH]
return RCSwitchProtocol(config[CONF_SYNC][0] * pl, config[CONF_SYNC][1] * pl,
config[CONF_ZERO][0] * pl, config[CONF_ZERO][1] * pl,
config[CONF_ONE][0] * pl, config[CONF_ONE][1] * pl,
config[CONF_INVERTED])
def binary_code(value):
code = 0
for val in value:
code <<= 1
code |= val == '1'
return HexInt(code)
def to_code(config): def to_code(config):
for conf in config: for conf in config:
pin = None pin = None

View File

@ -0,0 +1,23 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
from esphomeyaml.helpers import get_variable
DEPENDENCIES = ['esp32_ble_tracker']
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker)
}))
def to_code(config):
hub = None
for hub in get_variable(config[CONF_ESP32_BLE_ID]):
yield
rhs = hub.make_rssi_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
sensor.register_sensor(rhs, config)

View File

@ -0,0 +1,67 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_IIR_FILTER, CONF_MAKE_ID, \
CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, add, variable
DEPENDENCIES = ['i2c']
OVERSAMPLING_OPTIONS = {
'NONE': sensor.sensor_ns.BMP280_OVERSAMPLING_NONE,
'1X': sensor.sensor_ns.BMP280_OVERSAMPLING_1X,
'2X': sensor.sensor_ns.BMP280_OVERSAMPLING_2X,
'4X': sensor.sensor_ns.BMP280_OVERSAMPLING_4X,
'8X': sensor.sensor_ns.BMP280_OVERSAMPLING_8X,
'16X': sensor.sensor_ns.BMP280_OVERSAMPLING_16X,
}
IIR_FILTER_OPTIONS = {
'OFF': sensor.sensor_ns.BMP280_IIR_FILTER_OFF,
'2X': sensor.sensor_ns.BMP280_IIR_FILTER_2X,
'4X': sensor.sensor_ns.BMP280_IIR_FILTER_4X,
'8X': sensor.sensor_ns.BMP280_IIR_FILTER_8X,
'16X': sensor.sensor_ns.BMP280_IIR_FILTER_16X,
}
BMP280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)),
})
MakeBMP280Sensor = Application.MakeBMP280Sensor
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBMP280Sensor),
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA),
vol.Required(CONF_PRESSURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA),
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, cv.one_of(*IIR_FILTER_OPTIONS)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
rhs = App.make_bmp280_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
bmp280 = make.Pbmp280
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
add(bmp280.set_temperature_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
add(bmp280.set_pressure_oversampling(constant))
if CONF_IIR_FILTER in config:
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
add(bmp280.set_iir_filter(constant))
sensor.setup_sensor(bmp280.Pget_temperature_sensor(), make.Pmqtt_temperature,
config[CONF_TEMPERATURE])
sensor.setup_sensor(bmp280.Pget_pressure_sensor(), make.Pmqtt_pressure,
config[CONF_PRESSURE])
BUILD_FLAGS = '-DUSE_BMP280'

View File

@ -0,0 +1,73 @@
# coding=utf-8
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_UPDATE_INTERVAL, CONF_RANGE
from esphomeyaml.helpers import App, Pvariable, add
DEPENDENCIES = ['i2c']
CONF_FIELD_STRENGTH_X = 'field_strength_x'
CONF_FIELD_STRENGTH_Y = 'field_strength_y'
CONF_FIELD_STRENGTH_Z = 'field_strength_z'
CONF_HEADING = 'heading'
HMC5883LComponent = sensor.sensor_ns.HMC5883LComponent
HMC5883LFieldStrengthSensor = sensor.sensor_ns.HMC5883LFieldStrengthSensor
HMC5883LHeadingSensor = sensor.sensor_ns.HMC5883LHeadingSensor
HMC5883L_RANGES = {
88: sensor.sensor_ns.HMC5883L_RANGE_88_UT,
130: sensor.sensor_ns.HMC5883L_RANGE_130_UT,
190: sensor.sensor_ns.HMC5883L_RANGE_190_UT,
250: sensor.sensor_ns.HMC5883L_RANGE_250_UT,
400: sensor.sensor_ns.HMC5883L_RANGE_400_UT,
470: sensor.sensor_ns.HMC5883L_RANGE_470_UT,
560: sensor.sensor_ns.HMC5883L_RANGE_560_UT,
810: sensor.sensor_ns.HMC5883L_RANGE_810_UT,
}
def validate_range(value):
value = cv.string(value)
if value.endswith(u'µT') or value.endswith('uT'):
value = value[:-2]
return cv.one_of(*HMC5883L_RANGES)(value)
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HMC5883LComponent),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_FIELD_STRENGTH_X): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_FIELD_STRENGTH_Y): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_FIELD_STRENGTH_Z): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_HEADING): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
vol.Optional(CONF_RANGE): validate_range,
}), cv.has_at_least_one_key(CONF_FIELD_STRENGTH_X, CONF_FIELD_STRENGTH_Y, CONF_FIELD_STRENGTH_Z,
CONF_HEADING))
def to_code(config):
rhs = App.make_hmc5883l(config.get(CONF_UPDATE_INTERVAL))
hmc = Pvariable(config[CONF_ID], rhs)
if CONF_ADDRESS in config:
add(hmc.set_address(config[CONF_ADDRESS]))
if CONF_RANGE in config:
add(hmc.set_range(HMC5883L_RANGES[config[CONF_RANGE]]))
if CONF_FIELD_STRENGTH_X in config:
conf = config[CONF_FIELD_STRENGTH_X]
sensor.register_sensor(hmc.Pmake_x_sensor(conf[CONF_NAME]), conf)
if CONF_FIELD_STRENGTH_Y in config:
conf = config[CONF_FIELD_STRENGTH_Y]
sensor.register_sensor(hmc.Pmake_y_sensor(conf[CONF_NAME]), conf)
if CONF_FIELD_STRENGTH_Z in config:
conf = config[CONF_FIELD_STRENGTH_Z]
sensor.register_sensor(hmc.Pmake_z_sensor(conf[CONF_NAME]), conf)
if CONF_HEADING in config:
conf = config[CONF_HEADING]
sensor.register_sensor(hmc.Pmake_heading_sensor(conf[CONF_NAME]), conf)
BUILD_FLAGS = '-DUSE_HMC5883L'

View File

@ -0,0 +1,47 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import pins
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_GAIN, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, variable
MakeHX711Sensor = Application.MakeHX711Sensor
CONF_DOUT_PIN = 'dout_pin'
CONF_SCK_PIN = 'sck_pin'
GAINS = {
128: sensor.sensor_ns.HX711_GAIN_128,
32: sensor.sensor_ns.HX711_GAIN_32,
64: sensor.sensor_ns.HX711_GAIN_64,
}
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeHX711Sensor),
vol.Required(CONF_DOUT_PIN): pins.gpio_input_pin_schema,
vol.Required(CONF_SCK_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_GAIN): vol.All(cv.int_, cv.one_of(*GAINS)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}))
def to_code(config):
dout_pin = None
for dout_pin in gpio_input_pin_expression(config[CONF_DOUT_PIN]):
yield
sck_pin = None
for sck_pin in gpio_input_pin_expression(config[CONF_SCK_PIN]):
yield
rhs = App.make_hx711_sensor(config[CONF_NAME], dout_pin, sck_pin,
config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
if CONF_GAIN in config:
add(make.Phx711.set_gain(GAINS[CONF_GAIN]))
sensor.setup_sensor(make.Phx711, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_HX711'

View File

@ -0,0 +1,53 @@
# coding=utf-8
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_CURRENT, CONF_ID, CONF_MAX_CURRENT, \
CONF_MAX_VOLTAGE, CONF_NAME, CONF_POWER, CONF_UPDATE_INTERVAL, CONF_BUS_VOLTAGE, \
CONF_SHUNT_VOLTAGE, CONF_SHUNT_RESISTANCE
from esphomeyaml.helpers import App, Pvariable
DEPENDENCIES = ['i2c']
INA219Component = sensor.sensor_ns.INA219Component
INA219VoltageSensor = sensor.sensor_ns.INA219VoltageSensor
INA219CurrentSensor = sensor.sensor_ns.INA219CurrentSensor
INA219PowerSensor = sensor.sensor_ns.INA219PowerSensor
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA219Component),
vol.Optional(CONF_ADDRESS, default=0x40): cv.i2c_address,
vol.Optional(CONF_BUS_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_SHUNT_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_SHUNT_RESISTANCE, default=0.1): vol.All(cv.resistance,
vol.Range(min=0.0, max=32.0)),
vol.Optional(CONF_MAX_VOLTAGE, default=32.0): vol.All(cv.voltage, vol.Range(min=0.0, max=32.0)),
vol.Optional(CONF_MAX_CURRENT, default=3.2): vol.All(cv.current, vol.Range(min=0.0)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}), cv.has_at_least_one_key(CONF_BUS_VOLTAGE, CONF_SHUNT_VOLTAGE, CONF_CURRENT,
CONF_POWER))
def to_code(config):
rhs = App.make_ina219(config[CONF_SHUNT_RESISTANCE],
config[CONF_MAX_CURRENT], config[CONF_MAX_VOLTAGE],
config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL))
ina = Pvariable(config[CONF_ID], rhs)
if CONF_BUS_VOLTAGE in config:
conf = config[CONF_BUS_VOLTAGE]
sensor.register_sensor(ina.Pmake_bus_voltage_sensor(conf[CONF_NAME]), conf)
if CONF_SHUNT_VOLTAGE in config:
conf = config[CONF_SHUNT_VOLTAGE]
sensor.register_sensor(ina.Pmake_shunt_voltage_sensor(conf[CONF_NAME]), conf)
if CONF_CURRENT in config:
conf = config[CONF_CURRENT]
sensor.register_sensor(ina.Pmake_current_sensor(conf[CONF_NAME]), conf)
if CONF_POWER in config:
conf = config[CONF_POWER]
sensor.register_sensor(ina.Pmake_power_sensor(conf[CONF_NAME]), conf)
BUILD_FLAGS = '-DUSE_INA219'

View File

@ -0,0 +1,64 @@
# coding=utf-8
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, CONF_NAME, \
CONF_POWER, CONF_SHUNT_RESISTANCE, CONF_SHUNT_VOLTAGE, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Pvariable, add
DEPENDENCIES = ['i2c']
CONF_CHANNEL_1 = 'channel_1'
CONF_CHANNEL_2 = 'channel_2'
CONF_CHANNEL_3 = 'channel_3'
INA3221Component = sensor.sensor_ns.INA3221Component
INA3221VoltageSensor = sensor.sensor_ns.INA3221VoltageSensor
INA3221CurrentSensor = sensor.sensor_ns.INA3221CurrentSensor
INA3221PowerSensor = sensor.sensor_ns.INA3221PowerSensor
INA3221_CHANNEL_SCHEMA = vol.All(vol.Schema({
vol.Optional(CONF_BUS_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_SHUNT_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_SHUNT_RESISTANCE, default=0.1): vol.All(cv.resistance,
vol.Range(min=0.0, max=32.0)),
}), cv.has_at_least_one_key(CONF_BUS_VOLTAGE, CONF_SHUNT_VOLTAGE, CONF_CURRENT,
CONF_POWER))
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221Component),
vol.Optional(CONF_ADDRESS, default=0x40): cv.i2c_address,
vol.Optional(CONF_CHANNEL_1): INA3221_CHANNEL_SCHEMA,
vol.Optional(CONF_CHANNEL_2): INA3221_CHANNEL_SCHEMA,
vol.Optional(CONF_CHANNEL_3): INA3221_CHANNEL_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
rhs = App.make_ina3221(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL))
ina = Pvariable(config[CONF_ID], rhs)
for i, channel in enumerate([CONF_CHANNEL_1, CONF_CHANNEL_2, CONF_CHANNEL_3]):
if channel not in config:
continue
conf = config[channel]
if CONF_SHUNT_RESISTANCE in conf:
add(ina.set_shunt_resistance(i, conf[CONF_SHUNT_RESISTANCE]))
if CONF_BUS_VOLTAGE in conf:
c = conf[CONF_BUS_VOLTAGE]
sensor.register_sensor(ina.Pmake_bus_voltage_sensor(i, c[CONF_NAME]), c)
if CONF_SHUNT_VOLTAGE in conf:
c = conf[CONF_SHUNT_VOLTAGE]
sensor.register_sensor(ina.Pmake_shunt_voltage_sensor(i, c[CONF_NAME]), c)
if CONF_CURRENT in conf:
c = conf[CONF_CURRENT]
sensor.register_sensor(ina.Pmake_current_sensor(i, c[CONF_NAME]), c)
if CONF_POWER in conf:
c = conf[CONF_POWER]
sensor.register_sensor(ina.Pmake_power_sensor(i, c[CONF_NAME]), c)
BUILD_FLAGS = '-DUSE_INA3221'

View File

@ -3,33 +3,28 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.components import sensor from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN_CLOCK, CONF_PIN_CS, CONF_PIN_MISO, \ from esphomeyaml.components.spi import SPIComponent
CONF_UPDATE_INTERVAL from esphomeyaml.const import CONF_CS, CONF_MAKE_ID, CONF_NAME, CONF_SPI_ID, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, gpio_input_pin_expression, \ from esphomeyaml.helpers import App, Application, get_variable, gpio_output_pin_expression, variable
gpio_output_pin_expression, variable
MakeMAX6675Sensor = Application.MakeMAX6675Sensor MakeMAX6675Sensor = Application.MakeMAX6675Sensor
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeMAX6675Sensor), cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeMAX6675Sensor),
vol.Required(CONF_PIN_CS): pins.gpio_output_pin_schema, cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
vol.Required(CONF_PIN_CLOCK): pins.gpio_output_pin_schema, vol.Required(CONF_CS): pins.gpio_output_pin_schema,
vol.Required(CONF_PIN_MISO): pins.gpio_input_pin_schema,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
})) }))
def to_code(config): def to_code(config):
pin_cs = None spi = None
for pin_cs in gpio_output_pin_expression(config[CONF_PIN_CS]): for spi in get_variable(config[CONF_SPI_ID]):
yield yield
pin_clock = None cs = None
for pin_clock in gpio_output_pin_expression(config[CONF_PIN_CLOCK]): for cs in gpio_output_pin_expression(config[CONF_CS]):
yield yield
pin_miso = None rhs = App.make_max6675_sensor(config[CONF_NAME], spi, cs,
for pin_miso in gpio_input_pin_expression(config[CONF_PIN_MISO]):
yield
rhs = App.make_max6675_sensor(config[CONF_NAME], pin_cs, pin_clock, pin_miso,
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs) make = variable(config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(make.Pmax6675, make.Pmqtt, config) sensor.setup_sensor(make.Pmax6675, make.Pmqtt, config)

View File

@ -0,0 +1,38 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.components.uart import UARTComponent
from esphomeyaml.const import CONF_CO2, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, CONF_UART_ID, \
CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, get_variable, variable
DEPENDENCIES = ['uart']
MakeMHZ19Sensor = Application.MakeMHZ19Sensor
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeMHZ19Sensor),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
vol.Required(CONF_CO2): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
uart = None
for uart in get_variable(config[CONF_UART_ID]):
yield
rhs = App.make_mhz19_sensor(uart, config[CONF_CO2][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
mhz19 = make.Pmhz19
sensor.setup_sensor(mhz19.Pget_co2_sensor(), make.Pmqtt, config[CONF_CO2])
if CONF_TEMPERATURE in config:
sensor.register_sensor(mhz19.Pmake_temperature_sensor(config[CONF_TEMPERATURE][CONF_NAME]),
config[CONF_TEMPERATURE])
BUILD_FLAGS = '-DUSE_MHZ19'

View File

@ -0,0 +1,37 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_PRESSURE, \
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, add, variable
DEPENDENCIES = ['i2c']
MakeMS5611Sensor = Application.MakeMS5611Sensor
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeMS5611Sensor),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Required(CONF_PRESSURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
rhs = App.make_ms5611_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
if CONF_ADDRESS in config:
add(make.Pms5611.set_address(config[CONF_ADDRESS]))
sensor.setup_sensor(make.Pms5611.Pget_temperature_sensor(), make.Pmqtt_temperature,
config[CONF_TEMPERATURE])
sensor.setup_sensor(make.Pms5611.Pget_pressure_sensor(), make.Pmqtt_pressure,
config[CONF_PRESSURE])
BUILD_FLAGS = '-DUSE_MS5611'

View File

@ -0,0 +1,80 @@
# coding=utf-8
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_COLOR_TEMPERATURE, CONF_GAIN, CONF_ID, \
CONF_ILLUMINANCE, CONF_INTEGRATION_TIME, CONF_NAME, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Pvariable, add
DEPENDENCIES = ['i2c']
CONF_RED_CHANNEL = 'red_channel'
CONF_GREEN_CHANNEL = 'green_channel'
CONF_BLUE_CHANNEL = 'blue_channel'
CONF_CLEAR_CHANNEL = 'clear_channel'
TCS34725Component = sensor.sensor_ns.TCS34725Component
TCS34725_INTEGRATION_TIMES = {
'2.4ms': sensor.sensor_ns.TCS34725_INTEGRATION_TIME_2_4MS,
'24ms': sensor.sensor_ns.TCS34725_INTEGRATION_TIME_24MS,
'50ms': sensor.sensor_ns.TCS34725_INTEGRATION_TIME_50MS,
'101ms': sensor.sensor_ns.TCS34725_INTEGRATION_TIME_101MS,
'154ms': sensor.sensor_ns.TCS34725_INTEGRATION_TIME_154MS,
'700ms': sensor.sensor_ns.TCS34725_INTEGRATION_TIME_700MS,
}
TCS34725_GAINS = {
'1X': sensor.sensor_ns.TCS34725_GAIN_1X,
'4X': sensor.sensor_ns.TCS34725_GAIN_4X,
'16X': sensor.sensor_ns.TCS34725_GAIN_16X,
'60X': sensor.sensor_ns.TCS34725_GAIN_60X,
}
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TCS34725Component),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_RED_CHANNEL): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_GREEN_CHANNEL): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_BLUE_CHANNEL): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_CLEAR_CHANNEL): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_ILLUMINANCE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_COLOR_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_INTEGRATION_TIME): cv.one_of(*TCS34725_INTEGRATION_TIMES),
vol.Optional(CONF_GAIN): vol.All(vol.Upper, cv.one_of(*TCS34725_GAINS)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}), cv.has_at_least_one_key(CONF_RED_CHANNEL, CONF_GREEN_CHANNEL, CONF_BLUE_CHANNEL,
CONF_CLEAR_CHANNEL, CONF_ILLUMINANCE, CONF_COLOR_TEMPERATURE))
def to_code(config):
rhs = App.make_tcs34725(config.get(CONF_UPDATE_INTERVAL))
tcs = Pvariable(config[CONF_ID], rhs)
if CONF_ADDRESS in config:
add(tcs.set_address(config[CONF_ADDRESS]))
if CONF_INTEGRATION_TIME in config:
add(tcs.set_integration_time(TCS34725_INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]]))
if CONF_GAIN in config:
add(tcs.set_gain(TCS34725_GAINS[config[CONF_GAIN]]))
if CONF_RED_CHANNEL in config:
conf = config[CONF_RED_CHANNEL]
sensor.register_sensor(tcs.Pmake_red_sensor(conf[CONF_NAME]), conf)
if CONF_GREEN_CHANNEL in config:
conf = config[CONF_GREEN_CHANNEL]
sensor.register_sensor(tcs.Pmake_green_sensor(conf[CONF_NAME]), conf)
if CONF_BLUE_CHANNEL in config:
conf = config[CONF_BLUE_CHANNEL]
sensor.register_sensor(tcs.Pmake_blue_sensor(conf[CONF_NAME]), conf)
if CONF_CLEAR_CHANNEL in config:
conf = config[CONF_CLEAR_CHANNEL]
sensor.register_sensor(tcs.Pmake_clear_sensor(conf[CONF_NAME]), conf)
if CONF_ILLUMINANCE in config:
conf = config[CONF_ILLUMINANCE]
sensor.register_sensor(tcs.Pmake_illuminance_sensor(conf[CONF_NAME]), conf)
if CONF_COLOR_TEMPERATURE in config:
conf = config[CONF_COLOR_TEMPERATURE]
sensor.register_sensor(tcs.Pmake_color_temperature_sensor(conf[CONF_NAME]), conf)
BUILD_FLAGS = '-DUSE_TCS34725'

View File

@ -3,7 +3,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, process_lambda, variable, Application, float_, optional from esphomeyaml.helpers import App, process_lambda, variable, Application, float_, optional, add
MakeTemplateSensor = Application.MakeTemplateSensor MakeTemplateSensor = Application.MakeTemplateSensor
@ -15,14 +15,15 @@ PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
def to_code(config): def to_code(config):
rhs = App.make_template_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(make.Ptemplate_, make.Pmqtt, config)
template_ = None template_ = None
for template_ in process_lambda(config[CONF_LAMBDA], [], for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(float_)): return_type=optional.template(float_)):
yield yield
rhs = App.make_template_sensor(config[CONF_NAME], template_, add(make.Ptemplate_.set_template(template_))
config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR' BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR'

View File

@ -0,0 +1,22 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, variable
MakeUptimeSensor = Application.MakeUptimeSensor
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeUptimeSensor),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}))
def to_code(config):
rhs = App.make_uptime_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
make = variable(config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(make.Puptime, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_UPTIME_SENSOR'

View File

@ -0,0 +1,47 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
from esphomeyaml.const import CONF_BATTERY_LEVEL, CONF_CONDUCTIVITY, CONF_ILLUMINANCE, \
CONF_MAC_ADDRESS, CONF_MAKE_ID, CONF_MOISTURE, CONF_NAME, CONF_TEMPERATURE
from esphomeyaml.helpers import Pvariable, esphomelib_ns, get_variable
DEPENDENCIES = ['esp32_ble_tracker']
XiaomiMiFloraDevice = esphomelib_ns.XiaomiMiFloraDevice
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(XiaomiMiFloraDevice),
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker),
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Required(CONF_MOISTURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Required(CONF_ILLUMINANCE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Required(CONF_CONDUCTIVITY): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_BATTERY_LEVEL): cv.nameable(sensor.SENSOR_SCHEMA),
})
def to_code(config):
hub = None
for hub in get_variable(config[CONF_ESP32_BLE_ID]):
yield
rhs = hub.make_miflora_sensor(make_address_array(config[CONF_MAC_ADDRESS]))
dev = Pvariable(config[CONF_MAKE_ID], rhs)
if CONF_TEMPERATURE in config:
conf = config[CONF_TEMPERATURE]
sensor.register_sensor(dev.Pmake_temperature_sensor(conf[CONF_NAME]), conf)
if CONF_MOISTURE in config:
conf = config[CONF_MOISTURE]
sensor.register_sensor(dev.Pmake_moisture_sensor(conf[CONF_NAME]), conf)
if CONF_ILLUMINANCE in config:
conf = config[CONF_ILLUMINANCE]
sensor.register_sensor(dev.Pmake_illuminance_sensor(conf[CONF_NAME]), conf)
if CONF_CONDUCTIVITY in config:
conf = config[CONF_CONDUCTIVITY]
sensor.register_sensor(dev.Pmake_conductivity_sensor(conf[CONF_NAME]), conf)
if CONF_BATTERY_LEVEL in config:
conf = config[CONF_BATTERY_LEVEL]
sensor.register_sensor(dev.Pmake_battery_level_sensor(conf[CONF_NAME]), conf)

View File

@ -0,0 +1,37 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
from esphomeyaml.const import CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_MAKE_ID, \
CONF_NAME, CONF_TEMPERATURE
from esphomeyaml.helpers import Pvariable, esphomelib_ns, get_variable
DEPENDENCIES = ['esp32_ble_tracker']
XiaomiMiJiaDevice = esphomelib_ns.XiaomiMiJiaDevice
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(XiaomiMiJiaDevice),
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker),
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA),
vol.Optional(CONF_BATTERY_LEVEL): cv.nameable(sensor.SENSOR_SCHEMA),
})
def to_code(config):
hub = None
for hub in get_variable(config[CONF_ESP32_BLE_ID]):
yield
rhs = hub.make_mijia_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
make_address_array(config[CONF_MAC_ADDRESS]))
dev = Pvariable(config[CONF_MAKE_ID], rhs)
sensor.register_sensor(dev.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.register_sensor(dev.Pget_humidity_sensor(), config[CONF_HUMIDITY])
if CONF_BATTERY_LEVEL in config:
conf = config[CONF_BATTERY_LEVEL]
sensor.register_sensor(dev.Pmake_battery_level_sensor(conf[CONF_NAME]), conf)

View File

@ -0,0 +1,37 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import pins
from esphomeyaml.const import CONF_CLK, CONF_ID, CONF_MISO, CONF_MOSI
from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_input_pin_expression, \
gpio_output_pin_expression
SPIComponent = esphomelib_ns.SPIComponent
SPI_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(SPIComponent),
vol.Required(CONF_CLK): pins.gpio_output_pin_schema,
vol.Required(CONF_MISO): pins.gpio_input_pin_schema,
vol.Optional(CONF_MOSI): pins.gpio_output_pin_schema,
})
CONFIG_SCHEMA = vol.All(cv.ensure_list, [SPI_SCHEMA])
def to_code(config):
for conf in config:
clk = None
for clk in gpio_output_pin_expression(conf[CONF_CLK]):
yield
miso = None
for miso in gpio_input_pin_expression(conf[CONF_MISO]):
yield
mosi = None
if CONF_MOSI in conf:
for mosi in gpio_output_pin_expression(conf[CONF_MOSI]):
yield
rhs = App.init_spi(clk, miso, mosi)
Pvariable(conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_SPI'

View File

@ -4,10 +4,10 @@ from esphomeyaml import config_validation as cv, pins
from esphomeyaml.const import CONF_ID, CONF_PIN from esphomeyaml.const import CONF_ID, CONF_PIN
from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_output_pin_expression from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_output_pin_expression
StatusLED = esphomelib_ns.StatusLED StatusLEDComponent = esphomelib_ns.StatusLEDComponent
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(StatusLED), cv.GenerateID(): cv.declare_variable_id(StatusLEDComponent),
vol.Optional(CONF_PIN): pins.gpio_output_pin_schema, vol.Optional(CONF_PIN): pins.gpio_output_pin_schema,
}) })

View File

@ -2,15 +2,23 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import switch from esphomeyaml.components import switch
from esphomeyaml.components.remote_transmitter import RemoteTransmitterComponent, remote_ns from esphomeyaml.components.remote_transmitter import RC_SWITCH_RAW_SCHEMA, \
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \ RC_SWITCH_TYPE_A_SCHEMA, RC_SWITCH_TYPE_B_SCHEMA, RC_SWITCH_TYPE_C_SCHEMA, \
CONF_INVERTED, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \ RC_SWITCH_TYPE_D_SCHEMA, RemoteTransmitterComponent, binary_code, build_rc_switch_protocol, \
CONF_PANASONIC, CONF_RAW, CONF_REPEAT, CONF_SONY, CONF_TIMES, CONF_WAIT_TIME remote_ns
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_CHANNEL, CONF_CODE, \
CONF_COMMAND, CONF_DATA, CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_INVERTED, CONF_LG, \
CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, \
CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D,\
CONF_REPEAT, CONF_SONY, CONF_STATE, CONF_TIMES, \
CONF_WAIT_TIME
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, add, get_variable from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, add, get_variable
DEPENDENCIES = ['remote_transmitter'] DEPENDENCIES = ['remote_transmitter']
IR_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW] REMOTE_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW, CONF_RC_SWITCH_RAW,
CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C,
CONF_RC_SWITCH_TYPE_D]
CONF_REMOTE_TRANSMITTER_ID = 'remote_transmitter_id' CONF_REMOTE_TRANSMITTER_ID = 'remote_transmitter_id'
CONF_TRANSMITTER_ID = 'transmitter_id' CONF_TRANSMITTER_ID = 'transmitter_id'
@ -21,6 +29,13 @@ NECTransmitter = remote_ns.NECTransmitter
PanasonicTransmitter = remote_ns.PanasonicTransmitter PanasonicTransmitter = remote_ns.PanasonicTransmitter
RawTransmitter = remote_ns.RawTransmitter RawTransmitter = remote_ns.RawTransmitter
SonyTransmitter = remote_ns.SonyTransmitter SonyTransmitter = remote_ns.SonyTransmitter
RCSwitchProtocol = remote_ns.RCSwitchProtocol
rc_switch_protocols = remote_ns.rc_switch_protocols
RCSwitchRawTransmitter = remote_ns.RCSwitchRawTransmitter
RCSwitchTypeATransmitter = remote_ns.RCSwitchTypeATransmitter
RCSwitchTypeBTransmitter = remote_ns.RCSwitchTypeBTransmitter
RCSwitchTypeCTransmitter = remote_ns.RCSwitchTypeCTransmitter
RCSwitchTypeDTransmitter = remote_ns.RCSwitchTypeDTransmitter
validate_raw_data = [vol.Any(vol.Coerce(int), cv.time_period_microseconds)] validate_raw_data = [vol.Any(vol.Coerce(int), cv.time_period_microseconds)]
@ -45,42 +60,66 @@ PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
vol.Required(CONF_DATA): validate_raw_data, vol.Required(CONF_DATA): validate_raw_data,
vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)), vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)),
})), })),
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_C): RC_SWITCH_TYPE_C_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_D): RC_SWITCH_TYPE_D_SCHEMA,
vol.Optional(CONF_REPEAT): vol.Any(cv.positive_not_null_int, vol.Schema({ vol.Optional(CONF_REPEAT): vol.Any(cv.positive_not_null_int, vol.Schema({
vol.Required(CONF_TIMES): cv.positive_not_null_int, vol.Required(CONF_TIMES): cv.positive_not_null_int,
vol.Required(CONF_WAIT_TIME): cv.positive_time_period_microseconds, vol.Required(CONF_WAIT_TIME): cv.positive_time_period_microseconds,
})), })),
cv.GenerateID(CONF_REMOTE_TRANSMITTER_ID): cv.use_variable_id(RemoteTransmitterComponent), cv.GenerateID(CONF_REMOTE_TRANSMITTER_ID): cv.use_variable_id(RemoteTransmitterComponent),
cv.GenerateID(CONF_TRANSMITTER_ID): cv.declare_variable_id(RemoteTransmitter), cv.GenerateID(CONF_TRANSMITTER_ID): cv.declare_variable_id(RemoteTransmitter),
vol.Optional(CONF_INVERTED): cv.invalid("Remote Transmitters do not support inverted mode!"), vol.Optional(CONF_INVERTED): cv.invalid("Remote Transmitters do not support inverted mode!"),
}), cv.has_exactly_one_key(*IR_KEYS)) }), cv.has_exactly_one_key(*REMOTE_KEYS))
def transmitter_base(config): def transmitter_base(full_config):
if CONF_LG in config: name = full_config[CONF_NAME]
conf = config[CONF_LG] key, config = next((k, v) for k, v in full_config.items() if k in REMOTE_KEYS)
return LGTransmitter.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS])
elif CONF_NEC in config: if key == CONF_LG:
conf = config[CONF_NEC] return LGTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS])
return NECTransmitter.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND]) elif key == CONF_NEC:
elif CONF_PANASONIC in config: return NECTransmitter.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
conf = config[CONF_PANASONIC] elif key == CONF_PANASONIC:
return PanasonicTransmitter.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND]) return PanasonicTransmitter.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
elif CONF_SONY in config: elif key == CONF_SONY:
conf = config[CONF_SONY] return SonyTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS])
return SonyTransmitter.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS]) elif key == CONF_RAW:
elif CONF_RAW in config: if isinstance(config, dict):
conf = config[CONF_RAW] data = config[CONF_DATA]
if isinstance(conf, dict): carrier_frequency = config.get(CONF_CARRIER_FREQUENCY)
data = conf[CONF_DATA]
carrier_frequency = conf.get(CONF_CARRIER_FREQUENCY)
else: else:
data = conf data = config
carrier_frequency = None carrier_frequency = None
return RawTransmitter.new(config[CONF_NAME], ArrayInitializer(*data, multiline=False), return RawTransmitter.new(name, ArrayInitializer(*data, multiline=False),
carrier_frequency) carrier_frequency)
elif key == CONF_RC_SWITCH_RAW:
return RCSwitchRawTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
elif key == CONF_RC_SWITCH_TYPE_A:
return RCSwitchTypeATransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_GROUP]),
binary_code(config[CONF_DEVICE]),
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_B:
return RCSwitchTypeBTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
config[CONF_ADDRESS], config[CONF_CHANNEL],
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_C:
return RCSwitchTypeCTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
ord(config[CONF_FAMILY][0]) - ord('a'),
config[CONF_GROUP], config[CONF_DEVICE],
config[CONF_STATE])
elif key == CONF_RC_SWITCH_TYPE_D:
return RCSwitchTypeDTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
ord(config[CONF_GROUP][0]) - ord('a'),
config[CONF_DEVICE], config[CONF_STATE])
else: else:
raise ValueError("Unknown transmitter type {}".format(config)) raise NotImplementedError("Unknown transmitter type {}".format(config))
def to_code(config): def to_code(config):

View File

@ -23,6 +23,8 @@ def to_code(config):
rhs = App.make_template_switch(config[CONF_NAME]) rhs = App.make_template_switch(config[CONF_NAME])
make = variable(config[CONF_MAKE_ID], rhs) make = variable(config[CONF_MAKE_ID], rhs)
switch.setup_switch(make.Ptemplate_, make.Pmqtt, config)
if CONF_LAMBDA in config: if CONF_LAMBDA in config:
template_ = None template_ = None
for template_ in process_lambda(config[CONF_LAMBDA], [], for template_ in process_lambda(config[CONF_LAMBDA], [],
@ -38,7 +40,5 @@ def to_code(config):
if CONF_OPTIMISTIC in config: if CONF_OPTIMISTIC in config:
add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC])) add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC]))
switch.setup_switch(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_SWITCH' BUILD_FLAGS = '-DUSE_TEMPLATE_SWITCH'

View File

@ -0,0 +1,45 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import switch
from esphomeyaml.components.uart import UARTComponent
from esphomeyaml.const import CONF_DATA, CONF_INVERTED, CONF_MAKE_ID, CONF_NAME, CONF_UART_ID
from esphomeyaml.core import HexInt
from esphomeyaml.helpers import App, Application, ArrayInitializer, get_variable, variable
DEPENDENCIES = ['uart']
MakeUARTSwitch = Application.MakeUARTSwitch
def validate_data(value):
if isinstance(value, unicode):
return value.encode('utf-8')
elif isinstance(value, str):
return value
elif isinstance(value, list):
return vol.Schema([cv.hex_uint8_t])(value)
raise vol.Invalid("data must either be a string wrapped in quotes or a list of bytes")
PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeUARTSwitch),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
vol.Required(CONF_DATA): validate_data,
vol.Optional(CONF_INVERTED): cv.invalid("UART switches do not support inverted mode!"),
}))
def to_code(config):
uart = None
for uart in get_variable(config[CONF_UART_ID]):
yield
data = config[CONF_DATA]
if isinstance(data, str):
data = [HexInt(ord(x)) for x in data]
rhs = App.make_uart_switch(uart, config[CONF_NAME], ArrayInitializer(*data, multiline=False))
restart = variable(config[CONF_MAKE_ID], rhs)
switch.setup_switch(restart.Puart, restart.Pmqtt, config)
BUILD_FLAGS = '-DUSE_UART_SWITCH'

View File

@ -0,0 +1,33 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import pins
from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_RX, CONF_TX
from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_input_pin_expression, \
gpio_output_pin_expression
UARTComponent = esphomelib_ns.UARTComponent
SPI_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(UARTComponent),
vol.Required(CONF_TX): pins.gpio_output_pin_schema,
vol.Required(CONF_RX): pins.gpio_input_pin_schema,
vol.Required(CONF_BAUD_RATE): cv.positive_int,
})
CONFIG_SCHEMA = vol.All(cv.ensure_list, [SPI_SCHEMA])
def to_code(config):
for conf in config:
tx = None
for tx in gpio_output_pin_expression(conf[CONF_TX]):
yield
rx = None
for rx in gpio_input_pin_expression(conf[CONF_RX]):
yield
rhs = App.init_uart(tx, rx, conf[CONF_BAUD_RATE])
Pvariable(conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_UART'

View File

@ -12,7 +12,7 @@ from esphomeyaml import core, yaml_util, automation
from esphomeyaml.const import CONF_BOARD, CONF_BOARD_FLASH_MODE, CONF_ESPHOMEYAML, \ from esphomeyaml.const import CONF_BOARD, CONF_BOARD_FLASH_MODE, CONF_ESPHOMEYAML, \
CONF_LIBRARY_URI, CONF_NAME, CONF_PLATFORM, CONF_SIMPLIFY, CONF_USE_BUILD_FLAGS, CONF_WIFI, \ CONF_LIBRARY_URI, CONF_NAME, CONF_PLATFORM, CONF_SIMPLIFY, CONF_USE_BUILD_FLAGS, CONF_WIFI, \
ESP_PLATFORMS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_ON_BOOT, CONF_TRIGGER_ID, \ ESP_PLATFORMS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_ON_BOOT, CONF_TRIGGER_ID, \
CONF_PRIORITY, CONF_ON_SHUTDOWN CONF_PRIORITY, CONF_ON_SHUTDOWN, CONF_BUILD_PATH
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import App, add, color, esphomelib_ns, Pvariable, NoArg, const_char_p from esphomeyaml.helpers import App, add, color, esphomelib_ns, Pvariable, NoArg, const_char_p
@ -39,6 +39,7 @@ CORE_SCHEMA = vol.Schema({
vol.Optional(CONF_ON_SHUTDOWN): vol.All(cv.ensure_list, [automation.validate_automation({ vol.Optional(CONF_ON_SHUTDOWN): vol.All(cv.ensure_list, [automation.validate_automation({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ShutdownTrigger), cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ShutdownTrigger),
})]), })]),
vol.Optional(CONF_BUILD_PATH): cv.string,
}) })
REQUIRED_COMPONENTS = [ REQUIRED_COMPONENTS = [
@ -175,25 +176,28 @@ def validate_config(config):
_comp_error(ex, CONF_ESPHOMEYAML, config) _comp_error(ex, CONF_ESPHOMEYAML, config)
for domain, conf in config.iteritems(): for domain, conf in config.iteritems():
if domain == CONF_ESPHOMEYAML: domain = str(domain)
if domain == CONF_ESPHOMEYAML or domain.startswith('.'):
continue continue
if conf is None: if conf is None:
conf = {} conf = {}
component = get_component(domain) component = get_component(domain)
if component is None: if component is None:
result.add_error(u"Component not found: {}".format(domain)) result.add_error(u"Component not found: {}".format(domain), domain, conf)
continue 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),
domain, conf)
continue continue
success = True success = True
dependencies = getattr(component, 'DEPENDENCIES', []) dependencies = getattr(component, 'DEPENDENCIES', [])
for dependency in dependencies: for dependency in dependencies:
if dependency not in _ALL_COMPONENTS: if dependency not in _ALL_COMPONENTS:
result.add_error(u"Component {} requires component {}".format(domain, dependency)) result.add_error(u"Component {} requires component {}".format(domain, dependency),
domain, conf)
success = False success = False
if not success: if not success:
continue continue
@ -212,23 +216,25 @@ 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") 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)) result.add_error(u"No platform specified for {}".format(domain))
continue continue
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(domain, p_name)) result.add_error(u"Platform not found: {}".format(p_domain), p_domain, p_config)
continue continue
success = True success = True
dependencies = getattr(platform, 'DEPENDENCIES', []) dependencies = getattr(platform, 'DEPENDENCIES', [])
for dependency in dependencies: for dependency in dependencies:
if dependency not in _ALL_COMPONENTS: if dependency not in _ALL_COMPONENTS:
result.add_error(u"Platform {}.{} requires component {}".format(domain, p_name, result.add_error(
dependency)) u"Platform {} requires component {}".format(p_domain, dependency),
p_domain, p_config)
success = False success = False
if not success: if not success:
continue continue
@ -236,14 +242,15 @@ def validate_config(config):
esp_platforms = getattr(platform, 'ESP_PLATFORMS', ESP_PLATFORMS) esp_platforms = getattr(platform, 'ESP_PLATFORMS', ESP_PLATFORMS)
if core.ESP_PLATFORM not in esp_platforms: if core.ESP_PLATFORM not in esp_platforms:
result.add_error( result.add_error(
u"Platform {}.{} doesn't support {}.".format(domain, p_name, core.ESP_PLATFORM)) u"Platform {} doesn't support {}.".format(p_domain, core.ESP_PLATFORM),
p_domain, p_config)
continue continue
if hasattr(platform, u'PLATFORM_SCHEMA'): if hasattr(platform, u'PLATFORM_SCHEMA'):
try: try:
p_validated = platform.PLATFORM_SCHEMA(p_config) p_validated = platform.PLATFORM_SCHEMA(p_config)
except vol.Invalid as ex: except vol.Invalid as ex:
_comp_error(ex, u'{}.{}'.format(domain, p_name), p_config) _comp_error(ex, p_domain, p_config)
continue continue
platforms.append(p_validated) platforms.append(p_validated)
result[domain] = platforms result[domain] = platforms
@ -365,4 +372,4 @@ def read_config(path):
dump_dict(config, reset='red') dump_dict(config, reset='red')
print(color('reset')) print(color('reset'))
return None return None
return dict(**res) return OrderedDict(res)

View File

@ -360,20 +360,29 @@ METRIC_SUFFIXES = {
} }
def frequency(value): def float_with_unit(quantity, regex_suffix):
value = string(value) pattern = re.compile(r"^([-+]?[0-9]*\.?[0-9]*)\s*(\w*?)" + regex_suffix + "$")
match = re.match(r"^([-+]?[0-9]*\.?[0-9]*)\s*(\w*?)(?:Hz|HZ|hz)?$", value)
if match is None: def validator(value):
raise vol.Invalid(u"Expected frequency with unit, " match = pattern.match(string(value))
u"got {}".format(value))
mantissa = float(match.group(1)) if match is None:
if match.group(2) not in METRIC_SUFFIXES: raise vol.Invalid(u"Expected {} with unit, got {}".format(quantity, value))
raise vol.Invalid(u"Invalid frequency suffix {}".format(match.group(2)))
multiplier = METRIC_SUFFIXES[match.group(2)] mantissa = float(match.group(1))
return mantissa * multiplier if match.group(2) not in METRIC_SUFFIXES:
raise vol.Invalid(u"Invalid {} suffix {}".format(quantity, match.group(2)))
multiplier = METRIC_SUFFIXES[match.group(2)]
return mantissa * multiplier
return validator
frequency = float_with_unit("frequency", r"(Hz|HZ|hz)?")
resistance = float_with_unit("resistance", r"(Ω|Ω|ohm|Ohm|OHM)?")
current = float_with_unit("current", r"(a|A|amp|Amp|amps|Amps|ampere|Ampere)?")
voltage = float_with_unit("voltage", r"(v|V|volt|Volts)?")
def validate_bytes(value): def validate_bytes(value):

View File

@ -220,9 +220,10 @@ CONF_ON_VALUE = 'on_value'
CONF_ON_RAW_VALUE = 'on_raw_value' CONF_ON_RAW_VALUE = 'on_raw_value'
CONF_ON_VALUE_RANGE = 'on_value_range' CONF_ON_VALUE_RANGE = 'on_value_range'
CONF_ON_MESSAGE = 'on_message' CONF_ON_MESSAGE = 'on_message'
CONF_PIN_CS = 'pin_cs' CONF_CS = 'cs'
CONF_PIN_CLOCK = 'pin_clock' CONF_CLK = 'clk'
CONF_PIN_MISO = 'pin_miso' CONF_MISO = 'miso'
CONF_MOSI = 'mosi'
CONF_TURN_ON_ACTION = 'turn_on_action' CONF_TURN_ON_ACTION = 'turn_on_action'
CONF_TURN_OFF_ACTION = 'turn_off_action' CONF_TURN_OFF_ACTION = 'turn_off_action'
CONF_OPEN_ACTION = 'open_action' CONF_OPEN_ACTION = 'open_action'
@ -247,6 +248,47 @@ CONF_DELAYED_ON = 'delayed_on'
CONF_DELAYED_OFF = 'delayed_off' CONF_DELAYED_OFF = 'delayed_off'
CONF_UUID = 'uuid' CONF_UUID = 'uuid'
CONF_TYPE = 'type' CONF_TYPE = 'type'
CONF_SPI_ID = 'spi_id'
CONF_UART_ID = 'uart_id'
CONF_UID = 'uid'
CONF_TX = 'tx'
CONF_RX = 'rx'
CONF_CO2 = 'co2'
CONF_SHUNT_RESISTANCE = 'shunt_resistance'
CONF_MAX_CURRENT = 'max_current'
CONF_MAX_VOLTAGE = 'max_voltage'
CONF_CURRENT = 'current'
CONF_POWER = 'power'
CONF_BUS_VOLTAGE = 'bus_voltage'
CONF_SHUNT_VOLTAGE = 'shunt_voltage'
CONF_CONDITION = 'condition'
CONF_ELSE = 'else'
CONF_EFFECTS = 'effects'
CONF_RANDOM = 'random'
CONF_EFFECT_ID = 'effect_id'
CONF_COLORS = 'colors'
CONF_STATE = 'state'
CONF_DURATION = 'duration'
CONF_WIDTH = 'width'
CONF_ILLUMINANCE = 'illuminance'
CONF_COLOR_TEMPERATURE = 'color_temperature'
CONF_BATTERY_LEVEL = 'battery_level'
CONF_MOISTURE = 'moisture'
CONF_CONDUCTIVITY = 'conductivity'
CONF_RC_SWITCH_RAW = 'rc_switch_raw'
CONF_RC_SWITCH_TYPE_A = 'rc_switch_type_a'
CONF_RC_SWITCH_TYPE_B = 'rc_switch_type_b'
CONF_RC_SWITCH_TYPE_C = 'rc_switch_type_c'
CONF_RC_SWITCH_TYPE_D = 'rc_switch_type_d'
CONF_CODE = 'code'
CONF_PROTOCOL = 'protocol'
CONF_PULSE_LENGTH = 'pulse_length'
CONF_SYNC = 'sync'
CONF_ZERO = 'zero'
CONF_ONE = 'one'
CONF_GROUP = 'group'
CONF_DEVICE = 'device'
CONF_FAMILY = 'family'
ESP32_BOARDS = [ ESP32_BOARDS = [
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', 'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',

View File

@ -219,6 +219,8 @@ class ID(object):
return self.id return self.id
def __str__(self): def __str__(self):
if self.id is None:
return ''
return self.id return self.id
def __repr__(self): def __repr__(self):

View File

@ -66,7 +66,10 @@ class EsphomeyamlCommandWebSocket(tornado.websocket.WebSocketHandler):
break break
if data.endswith('\r') and random.randrange(100) < 90: if data.endswith('\r') and random.randrange(100) < 90:
continue continue
data = data.replace('\033', '\\033') try:
data = data.replace('\033', '\\033')
except UnicodeDecodeError:
data = data.encode('ascii', 'backslashreplace')
self.write_message({'event': 'line', 'data': data}) self.write_message({'event': 'line', 'data': data})
def proc_on_exit(self, returncode): def proc_on_exit(self, returncode):

View File

@ -297,8 +297,8 @@
<p> <p>
First, I need to know what this node should be called. Choose this name wisely, changing this First, I need to know what this node should be called. Choose this name wisely, changing this
later makes Over-The-Air Update attempts difficult. later makes Over-The-Air Update attempts difficult.
It may only contain the characters <code class="inlinecode">a-z</code>, Names must be <strong>lowercase</strong> and <strong>must not contain spaces</strong> (allowed characters: <code class="inlinecode">a-z</code>,
<code class="inlinecode">0-9</code> and <code class="inlinecode">_</code> <code class="inlinecode">0-9</code> and <code class="inlinecode">_</code>)
</p> </p>
<div class="input-field col s12"> <div class="input-field col s12">
<input id="node_name" class="validate" type="text" name="name" required> <input id="node_name" class="validate" type="text" name="name" required>

View File

@ -525,6 +525,17 @@ class MockObj(Expression):
def has_side_effects(self): def has_side_effects(self):
return self._has_side_effects return self._has_side_effects
def __getitem__(self, item):
next_op = u'.'
if isinstance(item, str) and item.startswith(u'P'):
item = item[1:]
next_op = u'->'
obj = MockObj(u'{}[{}]'.format(self.base, item), next_op)
obj.requires.append(self)
if isinstance(item, Expression):
obj.requires.append(item)
return obj
global_ns = MockObj('', '') global_ns = MockObj('', '')
float_ = global_ns.namespace('float') float_ = global_ns.namespace('float')

View File

@ -76,9 +76,13 @@ def clear_topic(config, topic, username=None, password=None, client_id=None):
_LOGGER.info(u"Clearing messages from %s", topic) _LOGGER.info(u"Clearing messages from %s", topic)
def on_message(client, userdata, msg): def on_message(client, userdata, msg):
if not msg.payload: if not msg.payload or not msg.retain:
return
try:
print(u"Clearing topic {}".format(msg.topic))
except UnicodeDecodeError:
print(u"Skipping non-UTF-8 topic (prohibited by MQTT standard)")
return return
print(u"Clearing topic {}".format(msg.topic))
client.publish(msg.topic, None, retain=True) client.publish(msg.topic, None, retain=True)
return initialize(config, [topic], on_message, username, password, client_id) return initialize(config, [topic], on_message, username, password, client_id)

View File

@ -179,10 +179,11 @@ def write_platformio_ini(content, path):
def write_platformio_project(config, path): def write_platformio_project(config, path):
platformio_ini = os.path.join(path, 'platformio.ini') platformio_ini = os.path.join(path, 'platformio.ini')
content = get_ini_content(config) content = get_ini_content(config)
if 'esp32_ble_beacon' in config: if 'esp32_ble_beacon' in config or 'esp32_ble_tracker' in config:
content += 'board_build.partitions = partitions.csv\n' content += 'board_build.partitions = partitions.csv\n'
partitions_csv = os.path.join(path, 'partitions.csv') partitions_csv = os.path.join(path, 'partitions.csv')
if not os.path.isfile(partitions_csv): if not os.path.isfile(partitions_csv):
mkdir_p(path)
with open(partitions_csv, "w") as f: with open(partitions_csv, "w") as f:
f.write("nvs, data, nvs, 0x009000, 0x005000,\n") f.write("nvs, data, nvs, 0x009000, 0x005000,\n")
f.write("otadata, data, ota, 0x00e000, 0x002000,\n") f.write("otadata, data, ota, 0x00e000, 0x002000,\n")

View File

@ -8,6 +8,7 @@ import uuid
from collections import OrderedDict from collections import OrderedDict
import yaml import yaml
import yaml.constructor
from esphomeyaml import core from esphomeyaml import core
from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress, Lambda, MACAddress, TimePeriod from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress, Lambda, MACAddress, TimePeriod
@ -63,14 +64,83 @@ def dump(dict_):
dict_, default_flow_style=False, allow_unicode=True) dict_, default_flow_style=False, allow_unicode=True)
def custom_construct_pairs(loader, node):
pairs = []
for kv in node.value:
if isinstance(kv, yaml.ScalarNode):
obj = loader.construct_object(kv)
if not isinstance(obj, dict):
raise ESPHomeYAMLError(
"Expected mapping for anchored include tag, got {}".format(type(obj)))
for key, value in obj.iteritems():
pairs.append((key, value))
else:
key_node, value_node = kv
key = loader.construct_object(key_node)
value = loader.construct_object(value_node)
pairs.append((key, value))
return pairs
def custom_flatten_mapping(loader, node):
pre_merge = []
post_merge = []
index = 0
while index < len(node.value):
if isinstance(node.value[index], yaml.ScalarNode):
index += 1
continue
key_node, value_node = node.value[index]
if key_node.tag == u'tag:yaml.org,2002:merge':
del node.value[index]
if isinstance(value_node, yaml.MappingNode):
custom_flatten_mapping(loader, value_node)
node.value = node.value[:index] + value_node.value + node.value[index:]
elif isinstance(value_node, yaml.SequenceNode):
submerge = []
for subnode in value_node.value:
if not isinstance(subnode, yaml.MappingNode):
raise yaml.constructor.ConstructorError(
"while constructing a mapping", node.start_mark,
"expected a mapping for merging, but found %{}".format(subnode.id),
subnode.start_mark)
custom_flatten_mapping(loader, subnode)
submerge.append(subnode.value)
# submerge.reverse()
node.value = node.value[:index] + submerge + node.value[index:]
elif isinstance(value_node, yaml.ScalarNode):
node.value = node.value[:index] + [value_node] + node.value[index:]
# post_merge.append(value_node)
else:
raise yaml.constructor.ConstructorError(
"while constructing a mapping", node.start_mark,
"expected a mapping or list of mappings for merging, "
"but found {}".format(value_node.id), value_node.start_mark)
elif key_node.tag == u'tag:yaml.org,2002:value':
key_node.tag = u'tag:yaml.org,2002:str'
index += 1
else:
index += 1
if pre_merge:
node.value = pre_merge + node.value
if post_merge:
node.value = node.value + post_merge
def _ordered_dict(loader, node): def _ordered_dict(loader, node):
"""Load YAML mappings into an ordered dictionary to preserve key order.""" """Load YAML mappings into an ordered dictionary to preserve key order."""
loader.flatten_mapping(node) custom_flatten_mapping(loader, node)
nodes = loader.construct_pairs(node) nodes = custom_construct_pairs(loader, node)
seen = {} seen = {}
for (key, _), (child_node, _) in zip(nodes, node.value): for (key, _), nv in zip(nodes, node.value):
line = child_node.start_mark.line if isinstance(nv, yaml.ScalarNode):
line = nv.start_mark.line
else:
line = nv[0].start_mark.line
try: try:
hash(key) hash(key)

View File

@ -1,3 +0,0 @@
# Examples
This directory contains some of the ESP32/ESP8266 nodes I use at my home.

View File

@ -1,127 +0,0 @@
esphomeyaml:
name: cabinet
platform: ESP32
board: nodemcu-32s
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.203
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: cabinet
password: '[PASSWORD]'
# This is the default
discovery: true
power_supply:
- id: 'atx'
pin:
number: 13
inverted: true
i2c:
sda: 14
scl: 27
frequency: 400000
pca9685:
- id: 'pca9685'
frequency: 500
output:
- platform: pca9685
pca9685_id: 'pca9685'
id: 'cabinet1_red'
channel: 14
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'cabinet1_green'
channel: 15
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'cabinet1_blue'
channel: 13
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'cabinet2_red'
channel: 11
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'cabinet2_green'
channel: 12
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'cabinet2_blue'
channel: 10
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'room_red'
channel: 8
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'room_green'
channel: 9
power_supply: 'atx'
- platform: pca9685
pca9685_id: 'pca9685'
id: 'room_blue'
channel: 7
power_supply: 'atx'
light:
- platform: rgb
name: 'Cabinet Light 1'
red: 'cabinet1_red'
green: 'cabinet1_green'
blue: 'cabinet1_blue'
- platform: rgb
name: 'Cabinet Light 2'
red: 'cabinet2_red'
green: 'cabinet2_green'
blue: 'cabinet2_blue'
- platform: rgb
name: 'Room Light'
red: 'room_red'
green: 'room_green'
blue: 'room_blue'
sensor:
- platform: dht
pin: 23
temperature:
name: 'Cabinet Temperature'
humidity:
name: 'Cabinet Humidity'
model: DHT22
binary_sensor:
- platform: gpio
pin: 25
name: 'Cabinet Motion'
device_class: motion
# Simple binary sensor that uses last will and birth messages to show
# node state
- platform: status
name: "Cabinet Status"
switch:
# Simple switch that restarts the ESP32
- platform: restart
name: "Cabinet Restart"

View File

@ -1,57 +0,0 @@
esphomeyaml:
name: dachboden
platform: ESP8266
board: nodemcuv2
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.212
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: dachboden
password: '[PASSWORD]'
# This is the default
discovery: true
dallas:
id: 'dallas'
pin: D1
sensor:
- platform: dht
pin: D3
temperature:
name: 'Dachboden Temperatur'
humidity:
name: 'Dachboden Luftfeuchtigkeit'
model: DHT22
- platform: dallas
dallas_id: 'dallas'
address: 0x01031663650aff28
name: "Dachboden Solar Süd Vorlauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x2b0416638fe6ff28
name: "Dachboden Solar Süd Rücklauf"
- platform: adc
pin: A0
name: "Dachboden Helligkeit"
binary_sensor:
- platform: status
name: "Dachboden Status"
switch:
- platform: restart
name: "Dachboden Neustart"

View File

@ -1,117 +0,0 @@
esphomeyaml:
name: heatpump
platform: ESP32
board: nodemcu-32s
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.204
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: heatpump
password: '[PASSWORD]'
# This is the default
discovery: true
dallas:
id: 'dallas'
pin: 15
sensor:
- platform: dht
pin: 0
temperature:
name: 'Outside Temperature'
humidity:
name: 'Outside Humidity'
model: DHT22
- platform: pulse_counter
pin: 12
unit_of_measurement: 'kW'
name: 'Stromverbrauch Wintergarten'
update_interval: 30s
expire_after: 60s
filters:
- multiply: 0.06
- platform: pulse_counter
pin: 13
unit_of_measurement: 'kW'
name: 'Stromverbrauch Wärmepumpe'
update_interval: 30s
expire_after: 60s
filters:
- multiply: 0.06
- platform: pulse_counter
pin: 14
unit_of_measurement: 'kW'
name: 'Stromverbrauch Gesamt'
update_interval: 30s
expire_after: 60s
filters:
- multiply: 0.06
- platform: dallas
dallas_id: 'dallas'
address: 0xfe0000031f1eaf28
name: "Boiler Temperatur Oben"
- platform: dallas
dallas_id: 'dallas'
address: 0xba0000031f0e5228
name: "Boiler Temperatur Unten"
- platform: dallas
dallas_id: 'dallas'
address: 0xa40000031f055028
name: "Boiler Temperatur Mitte"
- platform: dallas
dallas_id: 'dallas'
address: 0x790000031ee1dc28
name: "Heizung Rücklauf"
- platform: dallas
dallas_id: 'dallas'
address: 0xdd0000031efb0428
name: "Ölheizung Vorlauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x710000031f0e7e28
name: "Boiler Solar Rücklauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x92041703081aff28
name: "Boiler Solar Vorlauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x2c04173159f4ff28
name: "Heizung Vorlauf"
- platform: dallas
dallas_id: 'dallas'
address: 0xd10417315babff28
name: "Wärmepumpe Vorlauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x6c0517024a17ff28
name: "Boiler Heizung Vorlauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x7d04173139eeff28
name: "Wärmepumpe Rücklauf"
- platform: dallas
dallas_id: 'dallas'
address: 0x3204166398a5ff28
name: "Wärmepumpe Verdampfer"
binary_sensor:
- platform: status
name: "Heizung Status"
switch:
- platform: restart
name: "Heizung Neustart"

View File

@ -1,60 +0,0 @@
esphomeyaml:
name: kuche
platform: ESP8266
board: nodemcuv2
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.211
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: kuche
password: '[PASSWORD]'
# This is the default
discovery: true
dallas:
id: 'dallas'
pin: D1
sensor:
- platform: dallas
dallas_id: 'dallas'
address: 0x69041662d7f1ff28
name: "Küche Raumtemperatur"
- platform: dallas
dallas_id: 'dallas'
address: 0x800416636bebff28
name: "Küche Heizkörpertemperatur"
- platform: adc
pin: A0
name: "Küche Helligkeit"
output:
- platform: gpio
pin: D2
id: 'ventilator'
fan:
- platform: binary
output: 'ventilator'
name: 'Küche Heizkörper Ventilator'
binary_sensor:
- platform: status
name: "Küche Status"
switch:
- platform: restart
name: "Küche Neustart"

View File

@ -1,58 +0,0 @@
esphomeyaml:
name: lebensmittelkeller
platform: ESP8266
board: nodemcuv2
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.209
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: lebensmittelkeller
password: '[PASSWORD]'
# This is the default
discovery: true
sensor:
- platform: dht
pin: D3
temperature:
name: 'Lebensmittelkeller Temperatur'
humidity:
name: 'Lebensmittelkeller Feuchtigkeit'
model: DHT22
- platform: adc
pin: A0
name: "Lebensmittelkeller Helligkeit"
output:
- platform: gpio
pin: D4
id: 'ventilator'
fan:
- platform: binary
output: 'ventilator'
name: 'Lebensmittelkeller Ventilator'
switch:
- platform: gpio
pin: D2
name: 'Lebensmittelkeller Entfeuchter'
icon: 'mdi:water-off'
- platform: restart
name: "Lebensmittelkeller Neustart"
binary_sensor:
- platform: status
name: "Lebensmittelkeller Status"

View File

@ -1,344 +0,0 @@
esphomeyaml:
name: livingroom
platform: ESP32
board: nodemcu-32s
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.201
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: livingroom
password: '[PASSWORD]'
# This is the default
discovery: true
output:
- platform: ledc
id: 'fan_float'
frequency: 50000
pin: 22
bit_depth: 8
dallas:
pin: 23
id: dallas
sensor:
- platform: dallas
dallas_id: dallas
address: 0x1c0000031edd2a28
name: "Wohnzimmer Raumtemperatur"
filters:
- sliding_window_moving_average:
window_size: 15
send_every: 15
- filter_out: 85
- platform: dallas
dallas_id: dallas
address: 0x7a0315a8371eff28
name: "Wohnzimmer Heizkörpertemperatur"
update_interval: 30s
filters:
- sliding_window_moving_average:
window_size: 15
send_every: 15
- filter_out: 85
fan:
- platform: speed
output: 'fan_float'
name: 'Wohnzimmer Heizkörper Ventilator'
binary_sensor:
- platform: status
name: "Wohnzimmer Status"
ir_transmitter:
pin: 32
id: 'ir'
switch:
- platform: restart
name: "Wohnzimmer Neustart"
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV On"
panasonic:
address: 0x4004
command: 0x100BCBD
repeat: 25
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Off"
panasonic:
address: 0x4004
command: 0x100BCBD
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV SD Card"
panasonic:
address: 0x4004
command: 0x190D544
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Input TV"
panasonic:
address: 0x4004
command: 0x1400C4D
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Input AV"
panasonic:
address: 0x4004
command: 0x100A0A1
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Menu"
panasonic:
address: 0x4004
command: 0x1004A4B
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Aspect Ratio"
panasonic:
address: 0x4004
command: 0x1207B5A
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Viera Cast"
panasonic:
address: 0x4004
command: 0x190C958
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Direct TV REC"
panasonic:
address: 0x4004
command: 0x1909100
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Info"
panasonic:
address: 0x4004
command: 0x1009C9D
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Exit"
panasonic:
address: 0x4004
command: 0x100CBCA
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Viera Link"
panasonic:
address: 0x4004
command: 0x1908D1C
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Viera Tools"
panasonic:
address: 0x4004
command: 0x100F7F6
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Guide"
panasonic:
address: 0x4004
command: 0x190E170
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Up"
panasonic:
address: 0x4004
command: 0x1005253
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Left"
panasonic:
address: 0x4004
command: 0x1007273
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV OK"
panasonic:
address: 0x4004
command: 0x1009293
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Right"
panasonic:
address: 0x4004
command: 0x100F2F3
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Down"
panasonic:
address: 0x4004
command: 0x100D2D3
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Option"
panasonic:
address: 0x4004
command: 0x190E574
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Back"
panasonic:
address: 0x4004
command: 0x1002B2A
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Red"
panasonic:
address: 0x4004
command: 0x1000E0F
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Green"
panasonic:
address: 0x4004
command: 0x1000E0F # TODO: FIXME
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Yellow"
panasonic:
address: 0x4004
command: 0x1004E4F
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Blue"
panasonic:
address: 0x4004
command: 0x100CECF
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Text"
panasonic:
address: 0x4004
command: 0x180C041
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Subtitle"
panasonic:
address: 0x4004
command: 0x180A021
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Index"
panasonic:
address: 0x4004
command: 0x1801091
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Hold"
panasonic:
address: 0x4004
command: 0x1809011
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 1"
panasonic:
address: 0x4004
command: 0x1000809
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 2"
panasonic:
address: 0x4004
command: 0x1008889
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 3"
panasonic:
address: 0x4004
command: 0x1004849
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 4"
panasonic:
address: 0x4004
command: 0x100C8C9
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 5"
panasonic:
address: 0x4004
command: 0x1002829
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 6"
panasonic:
address: 0x4004
command: 0x100A8A9
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 7"
panasonic:
address: 0x4004
command: 0x1006869
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 8"
panasonic:
address: 0x4004
command: 0x100E8E9
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 9"
panasonic:
address: 0x4004
command: 0x1001819
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV 0"
panasonic:
address: 0x4004
command: 0x1009899
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Mute"
panasonic:
address: 0x4004
command: 0x1004C4D
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Last View"
panasonic:
address: 0x4004
command: 0x100ECED
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Volume Up"
panasonic:
address: 0x4004
command: 0x1000405
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Volume Down"
panasonic:
address: 0x4004
command: 0x1008485
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Program Up"
panasonic:
address: 0x4004
command: 0x1002C2D
- platform: ir_transmitter
ir_transmitter_id: 'ir'
name: "Panasonic TV Program Down"
panasonic:
address: 0x4004
command: 0x100ACAD

View File

@ -1,91 +0,0 @@
esphomeyaml:
name: <NAME_OF_NODE>
platform: ESP8266
board: esp01_1m
board_flash_mode: dout
wifi:
ssid: <YOUR_SSID>
password: <YOUR_PASSWORD>
mqtt:
broker: <YOUR_MQTT_BROKER>
username: <YOUR_USERNAME>
password: <YOUR_PASSWORD>
logger:
ota:
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: "Sonoff 4CH Button 1"
on_press:
then:
switch.toggle:
id: relay_1
- platform: gpio
pin:
number: GPIO9
mode: INPUT_PULLUP
inverted: True
name: "Sonoff 4CH Button 2"
on_press:
then:
switch.toggle:
id: relay_2
- platform: gpio
pin:
number: GPIO10
mode: INPUT_PULLUP
inverted: True
name: "Sonoff 4CH Button 3"
on_press:
then:
switch.toggle:
id: relay_3
- platform: gpio
pin:
number: GPIO14
mode: INPUT_PULLUP
inverted: True
name: "Sonoff 4CH Button 4"
on_press:
then:
switch.toggle:
id: relay_4
- platform: status
name: "Sonoff 4CH Status"
switch:
- platform: gpio
name: "Sonoff 4CH Relay 1"
pin: GPIO12
id: relay_1
- platform: gpio
name: "Sonoff 4CH Relay 2"
pin: GPIO5
id: relay_2
- platform: gpio
name: "Sonoff 4CH Relay 3"
pin: GPIO4
id: relay_3
- platform: gpio
name: "Sonoff 4CH Relay 4"
pin: GPIO15
id: relay_4
output:
- platform: esp8266_pwm
id: blue_led
pin: GPIO13
inverted: True
light:
- platform: monochromatic
name: "Sonoff 4CH Blue LED"
output: blue_led

View File

@ -1,50 +0,0 @@
esphomeyaml:
name: <NAME_OF_NODE>
platform: ESP8266
board: esp01_1m
board_flash_mode: dout
wifi:
ssid: <YOUR_SSID>
password: <YOUR_PASSWORD>
mqtt:
broker: <YOUR_MQTT_BROKER>
username: <YOUR_USERNAME>
password: <YOUR_PASSWORD>
logger:
ota:
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: "Sonoff S20 Button"
on_press:
then:
- switch.toggle:
id: relay
- platform: status
name: "Sonoff S20 Status"
switch:
- platform: gpio
name: "Sonoff S20 Relay"
pin: GPIO12
id: relay
output:
- platform: esp8266_pwm
id: s20_green_led
pin: GPIO13
inverted: True
light:
- platform: monochromatic
name: "Sonoff S20 Green LED"
output: s20_green_led

View File

@ -1,48 +0,0 @@
esphomeyaml:
name: terrasse
platform: ESP32
board: nodemcu-32s
logger:
level: verbose
wifi:
ssid: '[SSID]'
password: '[PASSWORD]'
manual_ip:
static_ip: 192.168.178.205
gateway: 192.168.178.1
subnet: 255.255.255.0
ota:
mqtt:
broker: 192.168.178.84
username: terrasse
password: '[PASSWORD]'
# This is the default
discovery: true
dallas:
pin: 25
id: dallas
sensor:
- platform: pulse_counter
pin: 34
name: "Terrasse Wind"
- platform: pulse_counter
pin: 39
name: "Terrasse Regen"
- platform: dallas
dallas_id: dallas
index: 0
name: "Terrasse Temperatur"
binary_sensor:
- platform: status
name: "Terrasse Status"
switch:
- platform: restart
name: "Terrasse Neustart"

View File

@ -17,6 +17,7 @@ disable=
invalid-name, invalid-name,
cyclic-import, cyclic-import,
redefined-builtin, redefined-builtin,
undefined-loop-variable,
additional-builtins= additional-builtins=