Automation API & Cleanup

This commit is contained in:
Otto Winter 2018-05-20 12:41:52 +02:00
parent 061798839d
commit 374ea7044c
No known key found for this signature in database
GPG key ID: DB66C0BE6013F97E
75 changed files with 1554 additions and 730 deletions

View file

@ -10,6 +10,7 @@ from esphomeyaml import core, mqtt, wizard, writer, yaml_util, const
from esphomeyaml.config import core_to_code, get_component, iter_components, read_config from esphomeyaml.config import core_to_code, get_component, iter_components, read_config
from esphomeyaml.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_LOGGER, \ from esphomeyaml.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_LOGGER, \
CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI
from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, add_task, \ from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, add_task, \
color, get_variable, indent, quote, statement, Expression color, get_variable, indent, quote, statement, Expression
@ -132,6 +133,8 @@ def write_cpp(config):
if isinstance(exp, Expression) and not exp.required: if isinstance(exp, Expression) and not exp.required:
continue continue
if isinstance(exp, AssignmentExpression) and not exp.obj.required: if isinstance(exp, AssignmentExpression) and not exp.obj.required:
if not exp.has_side_effects():
continue
exp = exp.rhs exp = exp.rhs
all_code.append(unicode(statement(exp))) all_code.append(unicode(statement(exp)))
@ -284,7 +287,11 @@ def main():
print(yaml_util.dump(config)) print(yaml_util.dump(config))
return 0 return 0
elif args.command == 'compile': elif args.command == 'compile':
try:
exit_code = write_cpp(config) exit_code = write_cpp(config)
except ESPHomeYAMLError as e:
_LOGGER.error(e)
return 1
if exit_code != 0: if exit_code != 0:
return exit_code return exit_code
exit_code = compile_program(config) exit_code = compile_program(config)

223
esphomeyaml/automation.py Normal file
View file

@ -0,0 +1,223 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, CONF_BLUE, \
CONF_BRIGHTNESS, CONF_CONDITION_ID, CONF_DELAY, CONF_EFFECT, CONF_FLASH_LENGTH, CONF_GREEN, \
CONF_ID, CONF_IF, CONF_LAMBDA, CONF_MAX, CONF_MIN, CONF_OR, CONF_PAYLOAD, CONF_QOS, \
CONF_RANGE, CONF_RED, CONF_RETAIN, CONF_THEN, CONF_TOPIC, CONF_TRANSITION_LENGTH, \
CONF_TRIGGER_ID, CONF_WHITE
from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, \
bool_, esphomelib_ns, float_, get_variable, process_lambda, std_string, templatable, uint32, \
uint8
CONF_MQTT_PUBLISH = 'mqtt.publish'
CONF_LIGHT_TOGGLE = 'light.toggle'
CONF_LIGHT_TURN_OFF = 'light.turn_off'
CONF_LIGHT_TURN_ON = 'light.turn_on'
CONF_SWITCH_TOGGLE = 'switch.toggle'
CONF_SWITCH_TURN_OFF = 'switch.turn_off'
CONF_SWITCH_TURN_ON = 'switch.turn_on'
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_LAMBDA]
ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
cv.GenerateID('action', CONF_ACTION_ID): cv.register_variable_id,
vol.Optional(CONF_DELAY): cv.positive_time_period_milliseconds,
vol.Optional(CONF_MQTT_PUBLISH): vol.Schema({
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos),
vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean),
}),
vol.Optional(CONF_LIGHT_TOGGLE): vol.Schema({
vol.Required(CONF_ID): cv.variable_id,
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
}),
vol.Optional(CONF_LIGHT_TURN_OFF): vol.Schema({
vol.Required(CONF_ID): cv.variable_id,
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
}),
vol.Optional(CONF_LIGHT_TURN_ON): vol.Schema({
vol.Required(CONF_ID): cv.variable_id,
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
vol.Optional(CONF_FLASH_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
vol.Optional(CONF_BRIGHTNESS): cv.templatable(cv.zero_to_one_float),
vol.Optional(CONF_RED): cv.templatable(cv.zero_to_one_float),
vol.Optional(CONF_GREEN): cv.templatable(cv.zero_to_one_float),
vol.Optional(CONF_BLUE): cv.templatable(cv.zero_to_one_float),
vol.Optional(CONF_WHITE): cv.templatable(cv.zero_to_one_float),
vol.Optional(CONF_EFFECT): cv.templatable(cv.string),
}),
vol.Optional(CONF_SWITCH_TOGGLE): vol.Schema({
vol.Required(CONF_ID): cv.variable_id,
}),
vol.Optional(CONF_SWITCH_TURN_OFF): vol.Schema({
vol.Required(CONF_ID): cv.variable_id,
}),
vol.Optional(CONF_SWITCH_TURN_ON): vol.Schema({
vol.Required(CONF_ID): cv.variable_id,
}),
vol.Optional(CONF_LAMBDA): cv.lambda_,
}, cv.has_at_exactly_one_key(*ACTION_KEYS))])
# pylint: disable=invalid-name
DelayAction = esphomelib_ns.DelayAction
LambdaAction = esphomelib_ns.LambdaAction
Automation = esphomelib_ns.Automation
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('condition', CONF_CONDITION_ID): cv.register_variable_id,
vol.Optional(CONF_AND): validate_recursive_condition,
vol.Optional(CONF_OR): validate_recursive_condition,
vol.Optional(CONF_RANGE): vol.All(vol.Schema({
vol.Optional(CONF_MIN): vol.Coerce(float),
vol.Optional(CONF_MAX): vol.Coerce(float),
}), cv.has_at_least_one_key(CONF_MIN, CONF_MAX)),
vol.Optional(CONF_LAMBDA): cv.lambda_,
}), cv.has_at_exactly_one_key(*CONDITION_KEYS)])
# pylint: disable=invalid-name
AndCondition = esphomelib_ns.AndCondition
OrCondition = esphomelib_ns.OrCondition
RangeCondition = esphomelib_ns.RangeCondition
LambdaCondition = esphomelib_ns.LambdaCondition
AUTOMATION_SCHEMA = vol.Schema({
cv.GenerateID('trigger', CONF_TRIGGER_ID): cv.register_variable_id,
cv.GenerateID('automation', CONF_AUTOMATION_ID): cv.register_variable_id,
vol.Optional(CONF_IF): CONDITIONS_SCHEMA,
vol.Required(CONF_THEN): ACTIONS_SCHEMA,
})
def build_condition(config, arg_type):
template_arg = TemplateArguments(arg_type)
if CONF_AND in config:
return AndCondition.new(template_arg, build_conditions(config[CONF_AND], template_arg))
if CONF_OR in config:
return OrCondition.new(template_arg, build_conditions(config[CONF_OR], template_arg))
if CONF_LAMBDA in config:
return LambdaCondition.new(template_arg,
process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')]))
if CONF_RANGE in config:
conf = config[CONF_RANGE]
rhs = RangeCondition.new(template_arg)
condition = Pvariable(RangeCondition.template(template_arg), config[CONF_CONDITION_ID], rhs)
if CONF_MIN in conf:
condition.set_min(templatable(conf[CONF_MIN], arg_type, float_))
if CONF_MAX in conf:
condition.set_max(templatable(conf[CONF_MAX], arg_type, float_))
return condition
raise ESPHomeYAMLError(u"Unsupported condition {}".format(config))
def build_conditions(config, arg_type):
return ArrayInitializer(*[build_condition(x, arg_type) for x in config])
def build_action(config, arg_type):
from esphomeyaml.components import light, mqtt, switch
template_arg = TemplateArguments(arg_type)
if CONF_DELAY in config:
rhs = App.register_component(DelayAction.new(template_arg))
action = Pvariable(DelayAction.template(template_arg), config[CONF_ACTION_ID], rhs)
add(action.set_delay(templatable(config[CONF_DELAY], arg_type, uint32)))
return action
elif CONF_LAMBDA in config:
rhs = LambdaAction.new(template_arg, process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')]))
return Pvariable(LambdaAction.template(template_arg), config[CONF_ACTION_ID], rhs)
elif CONF_MQTT_PUBLISH in config:
conf = config[CONF_MQTT_PUBLISH]
rhs = App.Pget_mqtt_client().Pmake_publish_action()
action = Pvariable(mqtt.MQTTPublishAction.template(template_arg), config[CONF_ACTION_ID],
rhs)
add(action.set_topic(templatable(conf[CONF_TOPIC], arg_type, std_string)))
add(action.set_payload(templatable(conf[CONF_PAYLOAD], arg_type, std_string)))
if CONF_QOS in conf:
add(action.set_qos(templatable(conf[CONF_QOS], arg_type, uint8)))
if CONF_RETAIN in conf:
add(action.set_retain(templatable(conf[CONF_RETAIN], arg_type, bool_)))
return action
elif CONF_LIGHT_TOGGLE in config:
conf = config[CONF_LIGHT_TOGGLE]
var = get_variable(conf[CONF_ID])
rhs = var.make_toggle_action(template_arg)
action = Pvariable(light.ToggleAction.template(template_arg), config[CONF_ACTION_ID], rhs)
if CONF_TRANSITION_LENGTH in conf:
add(action.set_transition_length(
templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32)
))
return action
elif CONF_LIGHT_TURN_OFF in config:
conf = config[CONF_LIGHT_TURN_OFF]
var = get_variable(conf[CONF_ID])
rhs = var.make_turn_off_action(template_arg)
action = Pvariable(light.TurnOffAction.template(template_arg), config[CONF_ACTION_ID], rhs)
if CONF_TRANSITION_LENGTH in conf:
add(action.set_transition_length(
templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32)
))
return action
elif CONF_LIGHT_TURN_ON in config:
conf = config[CONF_LIGHT_TURN_ON]
var = get_variable(conf[CONF_ID])
rhs = var.make_turn_on_action(template_arg)
action = Pvariable(light.TurnOnAction.template(template_arg), config[CONF_ACTION_ID], rhs)
if CONF_TRANSITION_LENGTH in conf:
add(action.set_transition_length(
templatable(conf[CONF_TRANSITION_LENGTH], arg_type, uint32)
))
if CONF_FLASH_LENGTH in conf:
add(action.set_flash_length(templatable(conf[CONF_FLASH_LENGTH], arg_type, uint32)))
if CONF_BRIGHTNESS in conf:
add(action.set_brightness(templatable(conf[CONF_BRIGHTNESS], arg_type, float_)))
if CONF_RED in conf:
add(action.set_red(templatable(conf[CONF_RED], arg_type, float_)))
if CONF_GREEN in conf:
add(action.set_green(templatable(conf[CONF_GREEN], arg_type, float_)))
if CONF_BLUE in conf:
add(action.set_blue(templatable(conf[CONF_BLUE], arg_type, float_)))
if CONF_WHITE in conf:
add(action.set_white(templatable(conf[CONF_WHITE], arg_type, float_)))
if CONF_EFFECT in conf:
add(action.set_effect(templatable(conf[CONF_EFFECT], arg_type, std_string)))
return action
elif CONF_SWITCH_TOGGLE in config:
conf = config[CONF_SWITCH_TOGGLE]
var = get_variable(conf[CONF_ID])
rhs = var.make_toggle_action(template_arg)
return Pvariable(switch.ToggleAction.template(arg_type), config[CONF_ACTION_ID], rhs)
elif CONF_SWITCH_TURN_OFF in config:
conf = config[CONF_SWITCH_TURN_OFF]
var = get_variable(conf[CONF_ID])
rhs = var.make_turn_off_action(template_arg)
return Pvariable(switch.TurnOffAction.template(arg_type), config[CONF_ACTION_ID], rhs)
elif CONF_SWITCH_TURN_ON in config:
conf = config[CONF_SWITCH_TURN_ON]
var = get_variable(conf[CONF_ID])
rhs = var.make_turn_on_action(template_arg)
return Pvariable(switch.TurnOnAction.template(arg_type), config[CONF_ACTION_ID], rhs)
raise ESPHomeYAMLError(u"Unsupported action {}".format(config))
def build_actions(config, arg_type):
return ArrayInitializer(*[build_action(x, arg_type) for x in config])
def build_automation(trigger, arg_type, config):
rhs = App.make_automation(trigger)
obj = Pvariable(Automation.template(arg_type), config[CONF_AUTOMATION_ID], rhs)
if CONF_IF in config:
add(obj.add_conditions(build_conditions(config[CONF_IF], arg_type)))
add(obj.add_actions(build_actions(config[CONF_THEN], arg_type)))

View file

@ -1,12 +1,13 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_RATE from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_RATE
from esphomeyaml.helpers import App, Pvariable from esphomeyaml.helpers import App, Pvariable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
ADS1115_COMPONENT_CLASS = 'sensor::ADS1115Component' ADS1115Component = sensor.sensor_ns.ADS1115Component
RATE_REMOVE_MESSAGE = """The rate option has been removed in 1.5.0 and is no longer required.""" RATE_REMOVE_MESSAGE = """The rate option has been removed in 1.5.0 and is no longer required."""
@ -23,7 +24,7 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
def to_code(config): def to_code(config):
for conf in config: for conf in config:
rhs = App.make_ads1115_component(conf[CONF_ADDRESS]) rhs = App.make_ads1115_component(conf[CONF_ADDRESS])
Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs) Pvariable(ADS1115Component, conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'

View file

@ -1,8 +1,11 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED, CONF_MQTT_ID from esphomeyaml import automation
from esphomeyaml.helpers import add, setup_mqtt_component, App, Pvariable from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INVERTED, CONF_MAX_LENGTH, \
CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, CONF_ON_PRESS, \
CONF_ON_RELEASE, CONF_TRIGGER_ID
from esphomeyaml.helpers import App, NoArg, Pvariable, add, esphomelib_ns, setup_mqtt_component
DEVICE_CLASSES = [ DEVICE_CLASSES = [
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
@ -11,39 +14,82 @@ DEVICE_CLASSES = [
'sound', 'vibration', 'window' 'sound', 'vibration', 'window'
] ]
DEVICE_CLASSES_MSG = "Unknown device class. Must be one of {}".format(', '.join(DEVICE_CLASSES))
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
vol.Optional(CONF_INVERTED): cv.boolean,
vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower,
vol.Any(*DEVICE_CLASSES, msg=DEVICE_CLASSES_MSG)),
})
MQTT_BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
}) })
MQTT_BINARY_SENSOR_ID_SCHEMA = MQTT_BINARY_SENSOR_SCHEMA.extend({ binary_sensor_ns = esphomelib_ns.namespace('binary_sensor')
PressTrigger = binary_sensor_ns.PressTrigger
ReleaseTrigger = binary_sensor_ns.ReleaseTrigger
ClickTrigger = binary_sensor_ns.ClickTrigger
DoubleClickTrigger = binary_sensor_ns.DoubleClickTrigger
BinarySensor = binary_sensor_ns.BinarySensor
MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent
BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
cv.GenerateID('mqtt_binary_sensor', CONF_MQTT_ID): cv.register_variable_id, cv.GenerateID('mqtt_binary_sensor', CONF_MQTT_ID): cv.register_variable_id,
cv.GenerateID('binary_sensor'): cv.register_variable_id,
vol.Optional(CONF_INVERTED): cv.boolean,
vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, cv.one_of(DEVICE_CLASSES)),
vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]),
vol.Optional(CONF_ON_RELEASE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]),
vol.Optional(CONF_ON_CLICK): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
})]),
vol.Optional(CONF_ON_DOUBLE_CLICK):
vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
})]),
}) })
def setup_binary_sensor(obj, config): def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config):
if CONF_DEVICE_CLASS in config: if CONF_DEVICE_CLASS in config:
add(obj.set_device_class(config[CONF_DEVICE_CLASS])) add(binary_sensor_var.set_device_class(config[CONF_DEVICE_CLASS]))
if CONF_INVERTED in config: if CONF_INVERTED in config:
add(obj.set_inverted(config[CONF_INVERTED])) add(binary_sensor_var.set_inverted(config[CONF_INVERTED]))
for conf in config.get(CONF_ON_PRESS, []):
rhs = binary_sensor_var.make_press_trigger()
trigger = Pvariable(PressTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, NoArg, conf)
for conf in config.get(CONF_ON_RELEASE, []):
rhs = binary_sensor_var.make_release_trigger()
trigger = Pvariable(ReleaseTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, NoArg, conf)
for conf in config.get(CONF_ON_CLICK, []):
rhs = binary_sensor_var.make_release_trigger(conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH])
trigger = Pvariable(ClickTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, NoArg, conf)
for conf in config.get(CONF_ON_DOUBLE_CLICK, []):
rhs = binary_sensor_var.make_double_click_trigger(conf[CONF_MIN_LENGTH],
conf[CONF_MAX_LENGTH])
trigger = Pvariable(DoubleClickTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, NoArg, conf)
setup_mqtt_component(mqtt_var, config)
def setup_mqtt_binary_sensor(obj, config): def setup_binary_sensor(binary_sensor_obj, mqtt_obj, config):
setup_mqtt_component(obj, config) binary_sensor_var = Pvariable(BinarySensor, config[CONF_ID], binary_sensor_obj,
has_side_effects=False)
mqtt_var = Pvariable(MQTTBinarySensorComponent, config[CONF_MQTT_ID], mqtt_obj,
has_side_effects=False)
setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config)
def register_binary_sensor(var, config): def register_binary_sensor(var, config):
setup_binary_sensor(var, config) binary_sensor_var = Pvariable(BinarySensor, config[CONF_ID], var,
rhs = App.register_binary_sensor(var) has_side_effects=True)
mqtt_sensor = Pvariable('binary_sensor::MQTTBinarySensorComponent', config[CONF_MQTT_ID], rhs) rhs = App.register_binary_sensor(binary_sensor_var)
setup_mqtt_binary_sensor(mqtt_sensor, config) mqtt_var = Pvariable(MQTTBinarySensorComponent, config[CONF_MQTT_ID], rhs,
has_side_effects=True)
setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_BINARY_SENSOR' BUILD_FLAGS = '-DUSE_BINARY_SENSOR'

View file

@ -2,9 +2,10 @@ 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_ID, CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32 from esphomeyaml.components.esp32_ble import ESP32BLETracker
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32
from esphomeyaml.core import HexInt, MACAddress from esphomeyaml.core import HexInt, MACAddress
from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable from esphomeyaml.helpers import ArrayInitializer, get_variable
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['esp32_ble'] DEPENDENCIES = ['esp32_ble']
@ -28,17 +29,15 @@ def validate_mac(value):
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('esp32_ble_device'): cv.register_variable_id,
vol.Required(CONF_MAC_ADDRESS): validate_mac, vol.Required(CONF_MAC_ADDRESS): validate_mac,
}).extend(binary_sensor.MQTT_BINARY_SENSOR_ID_SCHEMA.schema) }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema)
def to_code(config): def to_code(config):
hub = get_variable(None, type='ESP32BLETracker') hub = get_variable(None, type=ESP32BLETracker)
addr = [HexInt(i) for i in config[CONF_MAC_ADDRESS].parts] addr = [HexInt(i) for i in config[CONF_MAC_ADDRESS].parts]
rhs = hub.make_device(config[CONF_NAME], ArrayInitializer(*addr, multiline=False)) rhs = hub.make_device(config[CONF_NAME], ArrayInitializer(*addr, multiline=False))
device = Pvariable('ESP32BLEDevice', config[CONF_ID], rhs) binary_sensor.register_binary_sensor(rhs, config)
binary_sensor.register_binary_sensor(device, config)
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER' BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'

View file

@ -2,8 +2,9 @@ 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_ID, CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32 from esphomeyaml.components.esp32_touch import ESP32TouchComponent
from esphomeyaml.helpers import Pvariable, RawExpression, get_variable from esphomeyaml.const import CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32
from esphomeyaml.helpers import get_variable, global_ns
from esphomeyaml.pins import validate_gpio_pin from esphomeyaml.pins import validate_gpio_pin
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
@ -11,16 +12,16 @@ ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['esp32_touch'] DEPENDENCIES = ['esp32_touch']
TOUCH_PADS = { TOUCH_PADS = {
4: 'TOUCH_PAD_NUM0', 4: global_ns.TOUCH_PAD_NUM0,
0: 'TOUCH_PAD_NUM1', 0: global_ns.TOUCH_PAD_NUM1,
2: 'TOUCH_PAD_NUM2', 2: global_ns.TOUCH_PAD_NUM2,
15: 'TOUCH_PAD_NUM3', 15: global_ns.TOUCH_PAD_NUM3,
13: 'TOUCH_PAD_NUM4', 13: global_ns.TOUCH_PAD_NUM4,
12: 'TOUCH_PAD_NUM5', 12: global_ns.TOUCH_PAD_NUM5,
14: 'TOUCH_PAD_NUM6', 14: global_ns.TOUCH_PAD_NUM6,
27: 'TOUCH_PAD_NUM7', 27: global_ns.TOUCH_PAD_NUM7,
33: 'TOUCH_PAD_NUM8', 33: global_ns.TOUCH_PAD_NUM8,
32: 'TOUCH_PAD_NUM9', 32: global_ns.TOUCH_PAD_NUM9,
} }
@ -32,18 +33,16 @@ def validate_touch_pad(value):
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('esp32_touch_pad'): cv.register_variable_id,
vol.Required(CONF_PIN): validate_touch_pad, vol.Required(CONF_PIN): validate_touch_pad,
vol.Required(CONF_THRESHOLD): cv.uint16_t, vol.Required(CONF_THRESHOLD): cv.uint16_t,
}).extend(binary_sensor.MQTT_BINARY_SENSOR_ID_SCHEMA.schema) }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema)
def to_code(config): def to_code(config):
hub = get_variable(None, type='binary_sensor::ESP32TouchComponent') hub = get_variable(None, type=ESP32TouchComponent)
touch_pad = RawExpression(TOUCH_PADS[config[CONF_PIN]]) touch_pad = TOUCH_PADS[config[CONF_PIN]]
rhs = hub.make_touch_pad(config[CONF_NAME], touch_pad, config[CONF_THRESHOLD]) rhs = hub.make_touch_pad(config[CONF_NAME], touch_pad, config[CONF_THRESHOLD])
device = Pvariable('ESP32TouchBinarySensor', config[CONF_ID], rhs) binary_sensor.register_binary_sensor(rhs, config)
binary_sensor.register_binary_sensor(device, config)
BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR' BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR'

View file

@ -3,23 +3,22 @@ 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 binary_sensor from esphomeyaml.components import binary_sensor
from esphomeyaml.const import CONF_ID, CONF_INVERTED, CONF_NAME, CONF_PIN from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN
from esphomeyaml.helpers import App, add, variable, gpio_input_pin_expression from esphomeyaml.helpers import App, gpio_input_pin_expression, variable, Application
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('gpio_binary_sensor'): cv.register_variable_id, cv.GenerateID('gpio_binary_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN): pins.GPIO_INPUT_PIN_SCHEMA vol.Required(CONF_PIN): pins.GPIO_INPUT_PIN_SCHEMA
}).extend(binary_sensor.MQTT_BINARY_SENSOR_SCHEMA.schema) }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema)
MakeGPIOBinarySensor = Application.MakeGPIOBinarySensor
def to_code(config): def to_code(config):
rhs = App.make_gpio_binary_sensor(config[CONF_NAME], rhs = App.make_gpio_binary_sensor(config[CONF_NAME],
gpio_input_pin_expression(config[CONF_PIN])) gpio_input_pin_expression(config[CONF_PIN]))
gpio = variable('Application::MakeGPIOBinarySensor', config[CONF_ID], rhs) gpio = variable(MakeGPIOBinarySensor, config[CONF_MAKE_ID], rhs)
if CONF_INVERTED in config: binary_sensor.setup_binary_sensor(gpio.Pgpio, gpio.Pmqtt, config)
add(gpio.Pgpio.set_inverted(config[CONF_INVERTED]))
binary_sensor.setup_binary_sensor(gpio.Pgpio, config)
binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config)
BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR' BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR'

View file

@ -1,20 +1,21 @@
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_ID, CONF_NAME from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME
from esphomeyaml.helpers import App, variable from esphomeyaml.helpers import App, Application, variable
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('status_binary_sensor'): cv.register_variable_id, cv.GenerateID('status_binary_sensor', CONF_MAKE_ID): cv.register_variable_id,
}).extend(binary_sensor.MQTT_BINARY_SENSOR_SCHEMA.schema) }).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema)
MakeStatusBinarySensor = Application.MakeStatusBinarySensor
def to_code(config): def to_code(config):
rhs = App.make_status_binary_sensor(config[CONF_NAME]) rhs = App.make_status_binary_sensor(config[CONF_NAME])
status = variable('Application::MakeStatusBinarySensor', config[CONF_ID], rhs) status = variable(MakeStatusBinarySensor, config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(status.Pstatus, config) binary_sensor.setup_binary_sensor(status.Pstatus, status.Pmqtt, config)
binary_sensor.setup_mqtt_binary_sensor(status.Pmqtt, config)
BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR' BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR'

View file

@ -0,0 +1,23 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME
from esphomeyaml.helpers import App, Application, process_lambda, variable
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('template_binary_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_LAMBDA): cv.lambda_,
}).extend(binary_sensor.BINARY_SENSOR_SCHEMA.schema)
MakeTemplateBinarySensor = Application.MakeTemplateBinarySensor
def to_code(config):
template_ = process_lambda(config[CONF_LAMBDA], [])
rhs = App.make_template_binary_sensor(config[CONF_NAME], template_)
make = variable(MakeTemplateBinarySensor, config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'

View file

@ -0,0 +1,33 @@
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID
from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
cv.GenerateID('cover'): cv.register_variable_id,
cv.GenerateID('mqtt_cover', CONF_MQTT_ID): cv.register_variable_id,
})
cover_ns = esphomelib_ns.namespace('cover')
Cover = cover_ns.Cover
MQTTCoverComponent = cover_ns.MQTTCoverComponent
CoverState = cover_ns.CoverState
COVER_OPEN = cover_ns.COVER_OPEN
COVER_CLOSED = cover_ns.COVER_CLOSED
def setup_cover_core_(cover_var, mqtt_var, config):
setup_mqtt_component(mqtt_var, config)
def setup_cover(cover_obj, mqtt_obj, config):
cover_var = Pvariable(Cover, config[CONF_ID], cover_obj, has_side_effects=False)
mqtt_var = Pvariable(MQTTCoverComponent, config[CONF_MQTT_ID], mqtt_obj,
has_side_effects=False)
setup_cover_core_(cover_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_COVER'

View file

@ -0,0 +1,39 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import automation
from esphomeyaml.components import cover
from esphomeyaml.const import CONF_CLOSE_ACTION, CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, \
CONF_OPEN_ACTION, CONF_STOP_ACTION
from esphomeyaml.helpers import App, Application, NoArg, add, process_lambda, variable
PLATFORM_SCHEMA = cover.PLATFORM_SCHEMA.extend({
cv.GenerateID('template_cover', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_OPEN_ACTION): automation.ACTIONS_SCHEMA,
vol.Optional(CONF_CLOSE_ACTION): automation.ACTIONS_SCHEMA,
vol.Optional(CONF_STOP_ACTION): automation.ACTIONS_SCHEMA,
}).extend(cover.COVER_SCHEMA.schema)
MakeTemplateCover = Application.MakeTemplateCover
def to_code(config):
template_ = process_lambda(config[CONF_LAMBDA], [])
rhs = App.make_template_cover(config[CONF_NAME], template_)
make = variable(MakeTemplateCover, config[CONF_MAKE_ID], rhs)
if CONF_OPEN_ACTION in config:
actions = automation.build_actions(config[CONF_OPEN_ACTION], NoArg)
add(make.Ptemplate_.add_open_actions(actions))
if CONF_CLOSE_ACTION in config:
actions = automation.build_actions(config[CONF_CLOSE_ACTION], NoArg)
add(make.Ptemplate_.add_close_actions(actions))
if CONF_STOP_ACTION in config:
actions = automation.build_actions(config[CONF_STOP_ACTION], NoArg)
add(make.Ptemplate_.add_stop_actions(actions))
cover.setup_cover(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_COVER'

View file

@ -2,10 +2,11 @@ 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.const import CONF_ID, CONF_PIN, CONF_UPDATE_INTERVAL from esphomeyaml.const import CONF_ID, CONF_PIN, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Pvariable from esphomeyaml.helpers import App, Pvariable
DALLAS_COMPONENT_CLASS = 'sensor::DallasComponent' DallasComponent = sensor.sensor_ns.DallasComponent
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
cv.GenerateID('dallas'): cv.register_variable_id, cv.GenerateID('dallas'): cv.register_variable_id,
@ -17,7 +18,7 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
def to_code(config): def to_code(config):
for conf in config: for conf in config:
rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL)) rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL))
Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs) Pvariable(DallasComponent, conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'

View file

@ -3,7 +3,7 @@ import voluptuous as vol
from esphomeyaml import config_validation as cv, pins from esphomeyaml import config_validation as cv, pins
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \ from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \
CONF_SLEEP_DURATION, CONF_WAKEUP_PIN CONF_SLEEP_DURATION, CONF_WAKEUP_PIN
from esphomeyaml.helpers import App, Pvariable, add, gpio_input_pin_expression from esphomeyaml.helpers import App, Pvariable, add, gpio_input_pin_expression, esphomelib_ns
def validate_pin_number(value): def validate_pin_number(value):
@ -23,10 +23,12 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds, vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds,
}) })
DeepSleepComponent = esphomelib_ns.DeepSleepComponent
def to_code(config): def to_code(config):
rhs = App.make_deep_sleep_component() rhs = App.make_deep_sleep_component()
deep_sleep = Pvariable('DeepSleepComponent', config[CONF_ID], rhs) deep_sleep = Pvariable(DeepSleepComponent, config[CONF_ID], rhs)
if CONF_SLEEP_DURATION in config: if CONF_SLEEP_DURATION in config:
add(deep_sleep.set_sleep_duration(config[CONF_SLEEP_DURATION])) add(deep_sleep.set_sleep_duration(config[CONF_SLEEP_DURATION]))
if CONF_WAKEUP_PIN in config: if CONF_WAKEUP_PIN in config:

View file

@ -2,7 +2,7 @@ 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 from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
@ -11,10 +11,12 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
}) })
ESP32BLETracker = esphomelib_ns.ESP32BLETracker
def to_code(config): def to_code(config):
rhs = App.make_esp32_ble_tracker() rhs = App.make_esp32_ble_tracker()
ble = Pvariable('ESP32BLETracker', config[CONF_ID], rhs) ble = Pvariable(ESP32BLETracker, config[CONF_ID], rhs)
if CONF_SCAN_INTERVAL in config: if CONF_SCAN_INTERVAL in config:
add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL])) add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL]))

View file

@ -1,11 +1,12 @@
import voluptuous as vol import voluptuous as vol
from esphomeyaml import config_validation as cv from esphomeyaml import config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.const import CONF_ID, CONF_SETUP_MODE, CONF_IIR_FILTER, \ from esphomeyaml.const import CONF_ID, CONF_SETUP_MODE, CONF_IIR_FILTER, \
CONF_SLEEP_DURATION, CONF_MEASUREMENT_DURATION, CONF_LOW_VOLTAGE_REFERENCE, \ CONF_SLEEP_DURATION, CONF_MEASUREMENT_DURATION, CONF_LOW_VOLTAGE_REFERENCE, \
CONF_HIGH_VOLTAGE_REFERENCE, CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32 CONF_HIGH_VOLTAGE_REFERENCE, CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32
from esphomeyaml.core import TimePeriod from esphomeyaml.core import TimePeriod
from esphomeyaml.helpers import App, Pvariable, add from esphomeyaml.helpers import App, Pvariable, add, global_ns
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
@ -17,29 +18,27 @@ def validate_voltage(values):
value = cv.string(value) value = cv.string(value)
if not value.endswith('V'): if not value.endswith('V'):
value += 'V' value += 'V'
if value not in values: return cv.one_of(values)(value)
raise vol.Invalid('Must be one of {}'.format(values))
return value
return validator return validator
LOW_VOLTAGE_REFERENCE = { LOW_VOLTAGE_REFERENCE = {
'0.5V': 'TOUCH_LVOLT_0V5', '0.5V': global_ns.TOUCH_LVOLT_0V5,
'0.6V': 'TOUCH_LVOLT_0V6', '0.6V': global_ns.TOUCH_LVOLT_0V6,
'0.7V': 'TOUCH_LVOLT_0V7', '0.7V': global_ns.TOUCH_LVOLT_0V7,
'0.8V': 'TOUCH_LVOLT_0V8', '0.8V': global_ns.TOUCH_LVOLT_0V8,
} }
HIGH_VOLTAGE_REFERENCE = { HIGH_VOLTAGE_REFERENCE = {
'2.4V': 'TOUCH_HVOLT_2V4', '2.4V': global_ns.TOUCH_HVOLT_2V4,
'2.5V': 'TOUCH_HVOLT_2V5', '2.5V': global_ns.TOUCH_HVOLT_2V5,
'2.6V': 'TOUCH_HVOLT_2V6', '2.6V': global_ns.TOUCH_HVOLT_2V6,
'2.7V': 'TOUCH_HVOLT_2V7', '2.7V': global_ns.TOUCH_HVOLT_2V7,
} }
VOLTAGE_ATTENUATION = { VOLTAGE_ATTENUATION = {
'1.5V': 'TOUCH_HVOLT_ATTEN_1V5', '1.5V': global_ns.TOUCH_HVOLT_ATTEN_1V5,
'1V': 'TOUCH_HVOLT_ATTEN_1V', '1V': global_ns.TOUCH_HVOLT_ATTEN_1V,
'0.5V': 'TOUCH_HVOLT_ATTEN_0V5', '0.5V': global_ns.TOUCH_HVOLT_ATTEN_0V5,
'0V': 'TOUCH_HVOLT_ATTEN_0V', '0V': global_ns.TOUCH_HVOLT_ATTEN_0V,
} }
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
@ -55,10 +54,12 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_VOLTAGE_ATTENUATION): validate_voltage(VOLTAGE_ATTENUATION), vol.Optional(CONF_VOLTAGE_ATTENUATION): validate_voltage(VOLTAGE_ATTENUATION),
}) })
ESP32TouchComponent = binary_sensor.binary_sensor_ns.ESP32TouchComponent
def to_code(config): def to_code(config):
rhs = App.make_esp32_touch_component() rhs = App.make_esp32_touch_component()
touch = Pvariable('binary_sensor::ESP32TouchComponent', config[CONF_ID], rhs) touch = Pvariable(ESP32TouchComponent, config[CONF_ID], rhs)
if CONF_SETUP_MODE in config: if CONF_SETUP_MODE in config:
add(touch.set_setup_mode(config[CONF_SETUP_MODE])) add(touch.set_setup_mode(config[CONF_SETUP_MODE]))
if CONF_IIR_FILTER in config: if CONF_IIR_FILTER in config:

View file

@ -1,26 +1,43 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_OSCILLATION_COMMAND_TOPIC, CONF_OSCILLATION_STATE_TOPIC, \ from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_OSCILLATION_COMMAND_TOPIC, \
CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC
from esphomeyaml.helpers import add, setup_mqtt_component from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
cv.GenerateID('fan'): cv.register_variable_id,
cv.GenerateID('mqtt_fan', CONF_MQTT_ID): cv.register_variable_id,
vol.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.publish_topic, vol.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.publish_topic,
vol.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.subscribe_topic, vol.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.subscribe_topic,
}).extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA.schema) })
fan_ns = esphomelib_ns.namespace('fan')
FanState = fan_ns.FanState
MQTTFanComponent = fan_ns.MQTTFanComponent
MakeFan = Application.MakeFan
def setup_mqtt_fan(obj, config): def setup_fan_core_(fan_var, mqtt_var, config):
if CONF_OSCILLATION_STATE_TOPIC in config: if CONF_OSCILLATION_STATE_TOPIC in config:
add(obj.set_custom_oscillation_state_topic(config[CONF_OSCILLATION_STATE_TOPIC])) add(mqtt_var.set_custom_oscillation_state_topic(config[CONF_OSCILLATION_STATE_TOPIC]))
if CONF_OSCILLATION_COMMAND_TOPIC in config: if CONF_OSCILLATION_COMMAND_TOPIC in config:
add(obj.set_custom_oscillation_command_topic(config[CONF_OSCILLATION_COMMAND_TOPIC])) add(mqtt_var.set_custom_oscillation_command_topic(config[CONF_OSCILLATION_COMMAND_TOPIC]))
if CONF_SPEED_STATE_TOPIC in config: if CONF_SPEED_STATE_TOPIC in config:
add(obj.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC])) add(mqtt_var.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
if CONF_SPEED_COMMAND_TOPIC in config: if CONF_SPEED_COMMAND_TOPIC in config:
add(obj.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])) add(mqtt_var.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC]))
setup_mqtt_component(obj, config) setup_mqtt_component(mqtt_var, config)
def setup_fan(fan_obj, mqtt_obj, config):
fan_var = Pvariable(FanState, config[CONF_ID], fan_obj, has_side_effects=False)
mqtt_var = Pvariable(MQTTFanComponent, config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False)
setup_fan_core_(fan_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_FAN' BUILD_FLAGS = '-DUSE_FAN'

View file

@ -2,22 +2,23 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import fan from esphomeyaml.components import fan
from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT
from esphomeyaml.helpers import App, add, get_variable, variable from esphomeyaml.helpers import App, add, get_variable, variable
PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({
cv.GenerateID('binary_fan'): cv.register_variable_id, cv.GenerateID('binary_fan', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_OUTPUT): cv.variable_id, vol.Required(CONF_OUTPUT): cv.variable_id,
vol.Optional(CONF_OSCILLATION_OUTPUT): cv.variable_id, vol.Optional(CONF_OSCILLATION_OUTPUT): cv.variable_id,
}) }).extend(fan.FAN_SCHEMA.schema)
def to_code(config): def to_code(config):
output = get_variable(config[CONF_OUTPUT]) output = get_variable(config[CONF_OUTPUT])
rhs = App.make_fan(config[CONF_NAME]) rhs = App.make_fan(config[CONF_NAME])
fan_struct = variable('Application::MakeFan', config[CONF_ID], rhs) fan_struct = variable(fan.MakeFan, config[CONF_MAKE_ID], rhs)
add(fan_struct.Poutput.set_binary(output)) add(fan_struct.Poutput.set_binary(output))
if CONF_OSCILLATION_OUTPUT in config: if CONF_OSCILLATION_OUTPUT in config:
oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT])
add(fan_struct.Poutput.set_oscillation(oscillation_output)) add(fan_struct.Poutput.set_oscillation(oscillation_output))
fan.setup_mqtt_fan(fan_struct.Pmqtt, config)
fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config)

View file

@ -2,13 +2,13 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import fan from esphomeyaml.components import fan
from esphomeyaml.const import CONF_HIGH, CONF_ID, CONF_LOW, \ from esphomeyaml.const import CONF_HIGH, CONF_LOW, CONF_MAKE_ID, CONF_MEDIUM, CONF_NAME, \
CONF_MEDIUM, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT, CONF_SPEED, \ CONF_OSCILLATION_OUTPUT, CONF_OUTPUT, CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, \
CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC CONF_SPEED_STATE_TOPIC
from esphomeyaml.helpers import App, add, get_variable, variable from esphomeyaml.helpers import App, add, get_variable, variable
PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({
cv.GenerateID('speed_fan'): cv.register_variable_id, cv.GenerateID('speed_fan', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_OUTPUT): cv.variable_id, vol.Required(CONF_OUTPUT): cv.variable_id,
vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic, vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic,
vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic, vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic,
@ -18,13 +18,13 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({
vol.Required(CONF_MEDIUM): cv.zero_to_one_float, vol.Required(CONF_MEDIUM): cv.zero_to_one_float,
vol.Required(CONF_HIGH): cv.zero_to_one_float, vol.Required(CONF_HIGH): cv.zero_to_one_float,
}), }),
}) }).extend(fan.FAN_SCHEMA.schema)
def to_code(config): def to_code(config):
output = get_variable(config[CONF_OUTPUT]) output = get_variable(config[CONF_OUTPUT])
rhs = App.make_fan(config[CONF_NAME]) rhs = App.make_fan(config[CONF_NAME])
fan_struct = variable('Application::MakeFan', config[CONF_ID], rhs) fan_struct = variable(fan.MakeFan, config[CONF_MAKE_ID], rhs)
if CONF_SPEED in config: if CONF_SPEED in config:
speeds = config[CONF_SPEED] speeds = config[CONF_SPEED]
add(fan_struct.Poutput.set_speed(output, 0.0, add(fan_struct.Poutput.set_speed(output, 0.0,
@ -37,4 +37,5 @@ def to_code(config):
if CONF_OSCILLATION_OUTPUT in config: if CONF_OSCILLATION_OUTPUT in config:
oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT]) oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT])
add(fan_struct.Poutput.set_oscillation(oscillation_output)) add(fan_struct.Poutput.set_oscillation(oscillation_output))
fan.setup_mqtt_fan(fan_struct.Pmqtt, config)
fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config)

View file

@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID, \ from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID, \
CONF_RECEIVE_TIMEOUT CONF_RECEIVE_TIMEOUT
from esphomeyaml.helpers import App, add, Pvariable from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
cv.GenerateID('i2c'): cv.register_variable_id, cv.GenerateID('i2c'): cv.register_variable_id,
@ -15,10 +15,12 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_SCAN): cv.boolean, vol.Optional(CONF_SCAN): cv.boolean,
}) })
I2CComponent = esphomelib_ns.I2CComponent
def to_code(config): def to_code(config):
rhs = App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_SCAN)) rhs = App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_SCAN))
i2c = Pvariable('I2CComponent', config[CONF_ID], rhs) i2c = Pvariable(I2CComponent, config[CONF_ID], rhs)
if CONF_FREQUENCY in config: if CONF_FREQUENCY in config:
add(i2c.set_frequency(config[CONF_FREQUENCY])) add(i2c.set_frequency(config[CONF_FREQUENCY]))
if CONF_RECEIVE_TIMEOUT in config: if CONF_RECEIVE_TIMEOUT in config:

View file

@ -2,11 +2,10 @@ 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 switch
from esphomeyaml.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN from esphomeyaml.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN
from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression
IR_TRANSMITTER_COMPONENT_CLASS = 'switch_::IRTransmitterComponent'
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
cv.GenerateID('ir_transmitter'): cv.register_variable_id, cv.GenerateID('ir_transmitter'): cv.register_variable_id,
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
@ -14,12 +13,14 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
vol.Range(min=1, max=100)), vol.Range(min=1, max=100)),
})]) })])
IRTransmitterComponent = switch.switch_ns.namespace('IRTransmitterComponent')
def to_code(config): def to_code(config):
for conf in config: for conf in config:
pin = gpio_output_pin_expression(conf[CONF_PIN]) pin = gpio_output_pin_expression(conf[CONF_PIN])
rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT)) rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT))
Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs) Pvariable(IRTransmitterComponent, conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_IR_TRANSMITTER' BUILD_FLAGS = '-DUSE_IR_TRANSMITTER'

View file

@ -1,17 +1,40 @@
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \
from esphomeyaml.helpers import add CONF_MQTT_ID
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
}).extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA.schema) })
LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
cv.GenerateID('light'): cv.register_variable_id,
cv.GenerateID('mqtt_light', CONF_MQTT_ID): cv.register_variable_id,
})
light_ns = esphomelib_ns.namespace('light')
LightState = light_ns.LightState
MQTTJSONLightComponent = light_ns.MQTTJSONLightComponent
ToggleAction = light_ns.ToggleAction
TurnOffAction = light_ns.TurnOffAction
TurnOnAction = light_ns.TurnOnAction
MakeLight = Application.MakeLight
def setup_light_component(obj, config): def setup_light_core_(light_var, mqtt_var, config):
if CONF_DEFAULT_TRANSITION_LENGTH in config: if CONF_DEFAULT_TRANSITION_LENGTH in config:
add(obj.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(obj.set_gamma_correct(config[CONF_GAMMA_CORRECT])) add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
setup_mqtt_component(mqtt_var, config)
def setup_light(light_obj, mqtt_obj, config):
light_var = Pvariable(LightState, config[CONF_ID], light_obj, has_side_effects=False)
mqtt_var = Pvariable(MQTTJSONLightComponent, config[CONF_MQTT_ID], mqtt_obj,
has_side_effects=False)
setup_light_core_(light_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_LIGHT' BUILD_FLAGS = '-DUSE_LIGHT'

View file

@ -1,20 +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 light from esphomeyaml.components import light
from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_OUTPUT from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT
from esphomeyaml.helpers import App, get_variable, variable, setup_mqtt_component from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
cv.GenerateID('binary_light'): cv.register_variable_id, cv.GenerateID('binary_light', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_OUTPUT): cv.variable_id, vol.Required(CONF_OUTPUT): cv.variable_id,
}) }).extend(light.LIGHT_SCHEMA.schema)
def to_code(config): def to_code(config):
output = get_variable(config[CONF_OUTPUT]) output = get_variable(config[CONF_OUTPUT])
rhs = App.make_binary_light(config[CONF_NAME], output) rhs = App.make_binary_light(config[CONF_NAME], output)
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs)
setup_mqtt_component(light_struct.Pmqtt, config) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
light.setup_light_component(light_struct.Pstate, config)

View file

@ -4,10 +4,10 @@ import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.components import light from esphomeyaml.components import light
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_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
from esphomeyaml.helpers import App, RawExpression, TemplateArguments, add, get_variable, \ from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
setup_mqtt_component, variable get_variable, variable
TYPES = [ TYPES = [
'NEOPIXEL', 'NEOPIXEL',
@ -53,24 +53,26 @@ def validate(value):
PLATFORM_SCHEMA = vol.All(light.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = vol.All(light.PLATFORM_SCHEMA.extend({
cv.GenerateID('fast_led_clockless_light'): cv.register_variable_id, cv.GenerateID('fast_led_clockless_light', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_CHIPSET): vol.All(vol.Upper, vol.Any(*TYPES)), vol.Required(CONF_CHIPSET): vol.All(vol.Upper, cv.one_of(*TYPES)),
vol.Required(CONF_PIN): pins.output_pin, vol.Required(CONF_PIN): pins.output_pin,
vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int, vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds, vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, vol.Any(*RGB_ORDERS)), vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, cv.one_of(*RGB_ORDERS)),
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.variable_id, vol.Optional(CONF_POWER_SUPPLY): cv.variable_id,
}), validate) }).extend(light.LIGHT_SCHEMA.schema), validate)
MakeFastLEDLight = Application.MakeFastLEDLight
def to_code(config): def to_code(config):
rhs = App.make_fast_led_light(config[CONF_NAME]) rhs = App.make_fast_led_light(config[CONF_NAME])
make = variable('Application::MakeFastLEDLight', config[CONF_ID], rhs) make = variable(MakeFastLEDLight, config[CONF_MAKE_ID], rhs)
fast_led = make.Pfast_led fast_led = make.Pfast_led
rgb_order = None rgb_order = None
@ -87,8 +89,7 @@ def to_code(config):
power_supply = get_variable(config[CONF_POWER_SUPPLY]) power_supply = get_variable(config[CONF_POWER_SUPPLY])
add(fast_led.set_power_supply(power_supply)) add(fast_led.set_power_supply(power_supply))
setup_mqtt_component(make.Pmqtt, config) light.setup_light(make.Pstate, make.Pmqtt, config)
light.setup_light_component(make.Pstate, config)
BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT' BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'

View file

@ -4,10 +4,10 @@ import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.components import light from esphomeyaml.components import light
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_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, \
CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER
from esphomeyaml.helpers import App, RawExpression, TemplateArguments, add, get_variable, \ from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
setup_mqtt_component, variable get_variable, variable
CHIPSETS = [ CHIPSETS = [
'LPD8806', 'LPD8806',
@ -30,25 +30,27 @@ RGB_ORDERS = [
] ]
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
cv.GenerateID('fast_led_spi_light'): cv.register_variable_id, cv.GenerateID('fast_led_spi_light', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_CHIPSET): vol.All(vol.Upper, vol.Any(*CHIPSETS)), vol.Required(CONF_CHIPSET): vol.All(vol.Upper, cv.one_of(*CHIPSETS)),
vol.Required(CONF_DATA_PIN): pins.output_pin, vol.Required(CONF_DATA_PIN): pins.output_pin,
vol.Required(CONF_CLOCK_PIN): pins.output_pin, vol.Required(CONF_CLOCK_PIN): pins.output_pin,
vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int, vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, vol.Any(*RGB_ORDERS)), vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, cv.one_of(*RGB_ORDERS)),
vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds, vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
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.variable_id, vol.Optional(CONF_POWER_SUPPLY): cv.variable_id,
}) }).extend(light.LIGHT_SCHEMA.schema)
MakeFastLEDLight = Application.MakeFastLEDLight
def to_code(config): def to_code(config):
rhs = App.make_fast_led_light(config[CONF_NAME]) rhs = App.make_fast_led_light(config[CONF_NAME])
make = variable('Application::MakeFastLEDLight', config[CONF_ID], rhs) make = variable(MakeFastLEDLight, config[CONF_MAKE_ID], rhs)
fast_led = make.Pfast_led fast_led = make.Pfast_led
rgb_order = None rgb_order = None
@ -67,8 +69,7 @@ def to_code(config):
power_supply = get_variable(config[CONF_POWER_SUPPLY]) power_supply = get_variable(config[CONF_POWER_SUPPLY])
add(fast_led.set_power_supply(power_supply)) add(fast_led.set_power_supply(power_supply))
setup_mqtt_component(make.Pmqtt, config) light.setup_light(make.Pstate, make.Pmqtt, config)
light.setup_light_component(make.Pstate, config)
BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT' BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'

View file

@ -2,21 +2,20 @@ 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_ID, \ from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \
CONF_NAME, CONF_OUTPUT CONF_NAME, CONF_OUTPUT
from esphomeyaml.helpers import App, get_variable, setup_mqtt_component, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
cv.GenerateID('monochromatic_light'): cv.register_variable_id, cv.GenerateID('monochromatic_light', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_OUTPUT): cv.variable_id, vol.Required(CONF_OUTPUT): cv.variable_id,
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,
}) }).extend(light.LIGHT_SCHEMA.schema)
def to_code(config): def to_code(config):
output = get_variable(config[CONF_OUTPUT]) output = get_variable(config[CONF_OUTPUT])
rhs = App.make_monochromatic_light(config[CONF_NAME], output) rhs = App.make_monochromatic_light(config[CONF_NAME], output)
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs)
setup_mqtt_component(light_struct.Pmqtt, config) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
light.setup_light_component(light_struct.Pstate, config)

View file

@ -3,17 +3,17 @@ 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_ID, CONF_NAME, CONF_RED CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED
from esphomeyaml.helpers import App, get_variable, setup_mqtt_component, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
cv.GenerateID('rgb_light'): cv.register_variable_id, cv.GenerateID('rgb_light', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_RED): cv.variable_id, vol.Required(CONF_RED): cv.variable_id,
vol.Required(CONF_GREEN): cv.variable_id, vol.Required(CONF_GREEN): cv.variable_id,
vol.Required(CONF_BLUE): cv.variable_id, vol.Required(CONF_BLUE): cv.variable_id,
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,
}) }).extend(light.LIGHT_SCHEMA.schema)
def to_code(config): def to_code(config):
@ -21,6 +21,5 @@ def to_code(config):
green = get_variable(config[CONF_GREEN]) green = get_variable(config[CONF_GREEN])
blue = get_variable(config[CONF_BLUE]) blue = get_variable(config[CONF_BLUE])
rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue) rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue)
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs)
setup_mqtt_component(light_struct.Pmqtt, config) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
light.setup_light_component(light_struct.Pstate, config)

View file

@ -3,18 +3,18 @@ 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_ID, CONF_NAME, CONF_RED, CONF_WHITE CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE
from esphomeyaml.helpers import App, get_variable, setup_mqtt_component, variable from esphomeyaml.helpers import App, get_variable, variable
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
cv.GenerateID('rgbw_light'): cv.register_variable_id, cv.GenerateID('rgbw_light', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_RED): cv.variable_id, vol.Required(CONF_RED): cv.variable_id,
vol.Required(CONF_GREEN): cv.variable_id, vol.Required(CONF_GREEN): cv.variable_id,
vol.Required(CONF_BLUE): cv.variable_id, vol.Required(CONF_BLUE): cv.variable_id,
vol.Required(CONF_WHITE): cv.variable_id, vol.Required(CONF_WHITE): cv.variable_id,
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,
}) }).extend(light.LIGHT_SCHEMA.schema)
def to_code(config): def to_code(config):
@ -23,6 +23,5 @@ def to_code(config):
blue = get_variable(config[CONF_BLUE]) blue = get_variable(config[CONF_BLUE])
white = get_variable(config[CONF_WHITE]) white = get_variable(config[CONF_WHITE])
rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white) rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white)
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs) light_struct = variable(light.MakeLight, config[CONF_MAKE_ID], rhs)
setup_mqtt_component(light_struct.Pmqtt, config) light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
light.setup_light_component(light_struct.Pstate, config)

View file

@ -4,14 +4,34 @@ import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \ from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \
CONF_TX_BUFFER_SIZE CONF_TX_BUFFER_SIZE
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import App, Pvariable, RawExpression, add from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, global_ns
LOG_LEVELS = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE', 'VERY_VERBOSE'] LOG_LEVELS = {
'NONE': global_ns.ESPHOMELIB_LOG_LEVEL_NONE,
'ERROR': global_ns.ESPHOMELIB_LOG_LEVEL_ERROR,
'WARN': global_ns.ESPHOMELIB_LOG_LEVEL_WARN,
'INFO': global_ns.ESPHOMELIB_LOG_LEVEL_INFO,
'DEBUG': global_ns.ESPHOMELIB_LOG_LEVEL_DEBUG,
'VERBOSE': global_ns.ESPHOMELIB_LOG_LEVEL_VERBOSE,
'VERY_VERBOSE': global_ns.ESPHOMELIB_LOG_LEVEL_VERY_VERBOSE,
}
LOG_LEVEL_SEVERITY = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE', 'VERY_VERBOSE']
# pylint: disable=invalid-name # pylint: disable=invalid-name
is_log_level = vol.All(vol.Upper, vol.Any(*LOG_LEVELS)) is_log_level = vol.All(vol.Upper, cv.one_of(*LOG_LEVELS))
CONFIG_SCHEMA = vol.Schema({
def validate_local_no_higher_than_global(value):
global_level = value.get(CONF_LEVEL, 'DEBUG')
for tag, level in value.get(CONF_LOGS, {}).iteritems():
if LOG_LEVEL_SEVERITY.index(level) > LOG_LEVEL_SEVERITY.index(global_level):
raise ESPHomeYAMLError(u"The local log level {} for {} must be less severe than the "
u"global log level {}.".format(level, tag, global_level))
return value
CONFIG_SCHEMA = vol.All(vol.Schema({
cv.GenerateID(CONF_LOGGER): cv.register_variable_id, cv.GenerateID(CONF_LOGGER): cv.register_variable_id,
vol.Optional(CONF_BAUD_RATE): cv.positive_int, vol.Optional(CONF_BAUD_RATE): cv.positive_int,
vol.Optional(CONF_TX_BUFFER_SIZE): cv.positive_int, vol.Optional(CONF_TX_BUFFER_SIZE): cv.positive_int,
@ -19,33 +39,23 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_LOGS): vol.Schema({ vol.Optional(CONF_LOGS): vol.Schema({
cv.string: is_log_level, cv.string: is_log_level,
}) })
}) }), validate_local_no_higher_than_global)
LogComponent = esphomelib_ns.LogComponent
def esphomelib_log_level(level):
return u'ESPHOMELIB_LOG_LEVEL_{}'.format(level)
def exp_log_level(level):
return RawExpression(esphomelib_log_level(level))
def to_code(config): def to_code(config):
rhs = App.init_log(config.get(CONF_BAUD_RATE)) rhs = App.init_log(config.get(CONF_BAUD_RATE))
log = Pvariable(u'LogComponent', config[CONF_ID], rhs) log = Pvariable(LogComponent, config[CONF_ID], rhs)
if CONF_TX_BUFFER_SIZE in config: if CONF_TX_BUFFER_SIZE in config:
add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE])) add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE]))
if CONF_LEVEL in config: if CONF_LEVEL in config:
add(log.set_global_log_level(exp_log_level(config[CONF_LEVEL]))) add(log.set_global_log_level(LOG_LEVELS[config[CONF_LEVEL]]))
for tag, level in config.get(CONF_LOGS, {}).iteritems(): for tag, level in config.get(CONF_LOGS, {}).iteritems():
global_level = config.get(CONF_LEVEL, 'DEBUG') add(log.set_log_level(tag, LOG_LEVELS[level]))
if LOG_LEVELS.index(level) > LOG_LEVELS.index(global_level):
raise ESPHomeYAMLError(u"The local log level {} for {} must be less severe than the "
u"global log level {}.".format(level, tag, global_level))
add(log.set_log_level(tag, exp_log_level(level)))
def required_build_flags(config): def required_build_flags(config):
if CONF_LEVEL in config: if CONF_LEVEL in config:
return u'-DESPHOMELIB_LOG_LEVEL={}'.format(esphomelib_log_level(config[CONF_LEVEL])) return u'-DESPHOMELIB_LOG_LEVEL={}'.format(str(LOG_LEVELS[config[CONF_LEVEL]]))
return None return None

View file

@ -3,12 +3,14 @@ import re
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import automation
from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \ from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \
CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_SSL_FINGERPRINTS, CONF_ID, CONF_LOG_TOPIC, \ CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LOG_TOPIC, \
CONF_MQTT, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, \ CONF_MQTT, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \
CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_KEEPALIVE CONF_SSL_FINGERPRINTS, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \ CONF_WILL_MESSAGE
exp_empty_optional, RawExpression from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, \
TemplateArguments, add, esphomelib_ns, optional, std_string, RawExpression
def validate_message_just_topic(value): def validate_message_just_topic(value):
@ -18,7 +20,7 @@ def validate_message_just_topic(value):
MQTT_MESSAGE_BASE = vol.Schema({ MQTT_MESSAGE_BASE = vol.Schema({
vol.Required(CONF_TOPIC): cv.publish_topic, vol.Required(CONF_TOPIC): cv.publish_topic,
vol.Optional(CONF_QOS, default=0): vol.All(vol.Coerce(int), vol.In([0, 1, 2])), vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
vol.Optional(CONF_RETAIN, default=True): cv.boolean, vol.Optional(CONF_RETAIN, default=True): cv.boolean,
}) })
@ -28,12 +30,15 @@ MQTT_MESSAGE_SCHEMA = vol.Any(None, MQTT_MESSAGE_BASE.extend({
vol.Required(CONF_PAYLOAD): cv.mqtt_payload, vol.Required(CONF_PAYLOAD): cv.mqtt_payload,
})) }))
mqtt_ns = esphomelib_ns.namespace('mqtt')
MQTTMessage = mqtt_ns.MQTTMessage
MQTTClientComponent = mqtt_ns.MQTTClientComponent
MQTTPublishAction = mqtt_ns.MQTTPublishAction
MQTTMessageTrigger = mqtt_ns.MQTTMessageTrigger
def validate_broker(value): def validate_broker(value):
value = cv.string_strict(value) value = cv.string_strict(value)
if value.endswith(u'.local'):
raise vol.Invalid(u"MQTT server addresses ending with '.local' are currently unsupported."
u" Please use the static IP instead.")
if u':' in value: if u':' in value:
raise vol.Invalid(u"Please specify the port using the port: option") raise vol.Invalid(u"Please specify the port using the port: option")
if not value: if not value:
@ -65,14 +70,18 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266,
cv.ensure_list, [validate_fingerprint]), cv.ensure_list, [validate_fingerprint]),
vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds, vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds,
vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
vol.Required(CONF_TOPIC): cv.publish_topic,
vol.Optional(CONF_QOS, 0): cv.mqtt_qos,
})])
}) })
def exp_mqtt_message(config): def exp_mqtt_message(config):
if config is None: if config is None:
return exp_empty_optional('mqtt::MQTTMessage') return optional(TemplateArguments(MQTTMessage))
exp = StructInitializer( exp = StructInitializer(
'mqtt::MQTTMessage', MQTTMessage,
('topic', config[CONF_TOPIC]), ('topic', config[CONF_TOPIC]),
('payload', config.get(CONF_PAYLOAD, "")), ('payload', config.get(CONF_PAYLOAD, "")),
('qos', config[CONF_QOS]), ('qos', config[CONF_QOS]),
@ -84,7 +93,7 @@ def exp_mqtt_message(config):
def to_code(config): def to_code(config):
rhs = App.init_mqtt(config[CONF_BROKER], config[CONF_PORT], rhs = App.init_mqtt(config[CONF_BROKER], config[CONF_PORT],
config[CONF_USERNAME], config[CONF_PASSWORD]) config[CONF_USERNAME], config[CONF_PASSWORD])
mqtt = Pvariable('mqtt::MQTTClientComponent', config[CONF_ID], rhs) mqtt = Pvariable(MQTTClientComponent, config[CONF_ID], rhs)
if not config.get(CONF_DISCOVERY, True): if not config.get(CONF_DISCOVERY, True):
add(mqtt.disable_discovery()) add(mqtt.disable_discovery())
if CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config: if CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config:
@ -120,6 +129,11 @@ def to_code(config):
if CONF_KEEPALIVE in config: if CONF_KEEPALIVE in config:
add(mqtt.set_keep_alive(config[CONF_KEEPALIVE])) add(mqtt.set_keep_alive(config[CONF_KEEPALIVE]))
for conf in config.get(CONF_ON_MESSAGE, []):
rhs = mqtt.make_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS])
trigger = Pvariable(MQTTMessageTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, std_string, conf)
def required_build_flags(config): def required_build_flags(config):
if CONF_SSL_FINGERPRINTS in config: if CONF_SSL_FINGERPRINTS in config:

View file

@ -8,7 +8,7 @@ from esphomeyaml import core
from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \ from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import App, Pvariable, add from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -20,10 +20,12 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_PASSWORD): cv.string, vol.Optional(CONF_PASSWORD): cv.string,
}) })
OTAComponent = esphomelib_ns.OTAComponent
def to_code(config): def to_code(config):
rhs = App.init_ota() rhs = App.init_ota()
ota = Pvariable('OTAComponent', config[CONF_ID], rhs) ota = Pvariable(OTAComponent, config[CONF_ID], rhs)
if CONF_PASSWORD in config: if CONF_PASSWORD in config:
hash_ = hashlib.md5(config[CONF_PASSWORD].encode()).hexdigest() hash_ = hashlib.md5(config[CONF_PASSWORD].encode()).hexdigest()
add(ota.set_auth_password_hash(hash_)) add(ota.set_auth_password_hash(hash_))

View file

@ -1,19 +1,24 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_POWER_SUPPLY, CONF_INVERTED, CONF_MAX_POWER from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY
from esphomeyaml.helpers import get_variable, add from esphomeyaml.helpers import add, esphomelib_ns, get_variable
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
BINARY_OUTPUT_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({
vol.Optional(CONF_POWER_SUPPLY): cv.variable_id, vol.Optional(CONF_POWER_SUPPLY): cv.variable_id,
vol.Optional(CONF_INVERTED): cv.boolean, vol.Optional(CONF_INVERTED): cv.boolean,
}).extend(cv.REQUIRED_ID_SCHEMA.schema) })
FLOAT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ FLOAT_OUTPUT_SCHEMA = BINARY_OUTPUT_SCHEMA.extend({
vol.Optional(CONF_MAX_POWER): cv.zero_to_one_float, vol.Optional(CONF_MAX_POWER): cv.zero_to_one_float,
}) })
output_ns = esphomelib_ns.namespace('output')
def setup_output_platform(obj, config, skip_power_supply=False): def setup_output_platform(obj, config, skip_power_supply=False):
if CONF_INVERTED in config: if CONF_INVERTED in config:

View file

@ -15,15 +15,17 @@ def valid_pwm_pin(value):
return value return value
PLATFORM_SCHEMA = output.FLOAT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({
vol.Required(CONF_PIN): vol.All(pins.GPIO_INTERNAL_OUTPUT_PIN_SCHEMA, valid_pwm_pin), vol.Required(CONF_PIN): vol.All(pins.GPIO_INTERNAL_OUTPUT_PIN_SCHEMA, valid_pwm_pin),
}) }).extend(output.FLOAT_OUTPUT_SCHEMA.schema)
ESP8266PWMOutput = output.output_ns.ESP8266PWMOutput
def to_code(config): def to_code(config):
pin = gpio_output_pin_expression(config[CONF_PIN]) pin = gpio_output_pin_expression(config[CONF_PIN])
rhs = App.make_esp8266_pwm_output(pin) rhs = App.make_esp8266_pwm_output(pin)
gpio = Pvariable('output::ESP8266PWMOutput', config[CONF_ID], rhs) gpio = Pvariable(ESP8266PWMOutput, config[CONF_ID], rhs)
output.setup_output_platform(gpio, config) output.setup_output_platform(gpio, config)

View file

@ -7,13 +7,15 @@ from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression
PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
}) }).extend(output.BINARY_OUTPUT_SCHEMA.schema)
GPIOBinaryOutputComponent = output.output_ns.GPIOBinaryOutputComponent
def to_code(config): def to_code(config):
pin = gpio_output_pin_expression(config[CONF_PIN]) pin = gpio_output_pin_expression(config[CONF_PIN])
rhs = App.make_gpio_output(pin) rhs = App.make_gpio_output(pin)
gpio = Pvariable('output::GPIOBinaryOutputComponent', config[CONF_ID], rhs) gpio = Pvariable(GPIOBinaryOutputComponent, config[CONF_ID], rhs)
output.setup_output_platform(gpio, config) output.setup_output_platform(gpio, config)

View file

@ -19,12 +19,15 @@ def validate_frequency_bit_depth(obj):
return obj return obj
PLATFORM_SCHEMA = vol.All(output.FLOAT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = vol.All(output.PLATFORM_SCHEMA.extend({
vol.Required(CONF_PIN): vol.All(pins.output_pin, vol.Range(min=0, max=33)), vol.Required(CONF_PIN): vol.All(pins.output_pin, vol.Range(min=0, max=33)),
vol.Optional(CONF_FREQUENCY): cv.frequency, vol.Optional(CONF_FREQUENCY): cv.frequency,
vol.Optional(CONF_BIT_DEPTH): vol.All(vol.Coerce(int), vol.Range(min=1, max=15)), vol.Optional(CONF_BIT_DEPTH): vol.All(vol.Coerce(int), vol.Range(min=1, max=15)),
vol.Optional(CONF_CHANNEL): vol.All(vol.Coerce(int), vol.Range(min=0, max=15)) vol.Optional(CONF_CHANNEL): vol.All(vol.Coerce(int), vol.Range(min=0, max=15))
}), validate_frequency_bit_depth) }).extend(output.FLOAT_OUTPUT_SCHEMA.schema), validate_frequency_bit_depth)
LEDCOutputComponent = output.output_ns.LEDCOutputComponent
def to_code(config): def to_code(config):
@ -32,7 +35,7 @@ def to_code(config):
if frequency is None and CONF_BIT_DEPTH in config: if frequency is None and CONF_BIT_DEPTH in config:
frequency = 1000 frequency = 1000
rhs = App.make_ledc_output(config[CONF_PIN], frequency, config.get(CONF_BIT_DEPTH)) rhs = App.make_ledc_output(config[CONF_PIN], frequency, config.get(CONF_BIT_DEPTH))
ledc = Pvariable('output::LEDCOutputComponent', config[CONF_ID], rhs) ledc = Pvariable(LEDCOutputComponent, config[CONF_ID], rhs)
if CONF_CHANNEL in config: if CONF_CHANNEL in config:
add(ledc.set_channel(config[CONF_CHANNEL])) add(ledc.set_channel(config[CONF_CHANNEL]))
output.setup_output_platform(ledc, config) output.setup_output_platform(ledc, config)

View file

@ -2,26 +2,28 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import output from esphomeyaml.components import output
from esphomeyaml.components.pca9685 import PCA9685_COMPONENT_TYPE from esphomeyaml.components.pca9685 import PCA9685OutputComponent
from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_PCA9685_ID, CONF_POWER_SUPPLY from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_PCA9685_ID, CONF_POWER_SUPPLY
from esphomeyaml.helpers import Pvariable, get_variable from esphomeyaml.helpers import Pvariable, get_variable
DEPENDENCIES = ['pca9685'] DEPENDENCIES = ['pca9685']
PLATFORM_SCHEMA = output.FLOAT_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = output.PLATFORM_SCHEMA.extend({
vol.Required(CONF_CHANNEL): vol.All(vol.Coerce(int), vol.Required(CONF_CHANNEL): vol.All(vol.Coerce(int),
vol.Range(min=0, max=15)), vol.Range(min=0, max=15)),
vol.Optional(CONF_PCA9685_ID): cv.variable_id, vol.Optional(CONF_PCA9685_ID): cv.variable_id,
}) }).extend(output.FLOAT_OUTPUT_SCHEMA.schema)
Channel = PCA9685OutputComponent.Channel
def to_code(config): def to_code(config):
power_supply = None power_supply = None
if CONF_POWER_SUPPLY in config: if CONF_POWER_SUPPLY in config:
power_supply = get_variable(config[CONF_POWER_SUPPLY]) power_supply = get_variable(config[CONF_POWER_SUPPLY])
pca9685 = get_variable(config.get(CONF_PCA9685_ID), PCA9685_COMPONENT_TYPE) pca9685 = get_variable(config.get(CONF_PCA9685_ID), PCA9685OutputComponent)
rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply) rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply)
out = Pvariable('output::PCA9685OutputComponent::Channel', config[CONF_ID], rhs) out = Pvariable(Channel, config[CONF_ID], rhs)
output.setup_output_platform(out, config, skip_power_supply=True) output.setup_output_platform(out, config, skip_power_supply=True)

View file

@ -1,14 +1,13 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import output
from esphomeyaml.const import CONF_ADDRESS, CONF_FREQUENCY, CONF_ID, CONF_PHASE_BALANCER from esphomeyaml.const import CONF_ADDRESS, CONF_FREQUENCY, CONF_ID, CONF_PHASE_BALANCER
from esphomeyaml.helpers import App, HexIntLiteral, Pvariable, RawExpression, add from esphomeyaml.helpers import App, HexIntLiteral, Pvariable, add
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
PHASE_BALANCERS = ['None', 'Linear', 'Weaved'] PCA9685OutputComponent = output.output_ns.namespace('PCA9685OutputComponent')
PCA9685_COMPONENT_TYPE = 'output::PCA9685OutputComponent'
PHASE_BALANCER_MESSAGE = ("The phase_balancer option has been removed in version 1.5.0. " PHASE_BALANCER_MESSAGE = ("The phase_balancer option has been removed in version 1.5.0. "
"esphomelib will now automatically choose a suitable phase balancer.") "esphomelib will now automatically choose a suitable phase balancer.")
@ -28,13 +27,9 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCA9685_SCHEMA])
def to_code(config): def to_code(config):
for conf in config: for conf in config:
rhs = App.make_pca9685_component(conf.get(CONF_FREQUENCY)) rhs = App.make_pca9685_component(conf.get(CONF_FREQUENCY))
pca9685 = Pvariable(PCA9685_COMPONENT_TYPE, conf[CONF_ID], rhs) pca9685 = Pvariable(PCA9685OutputComponent, conf[CONF_ID], rhs)
if CONF_ADDRESS in conf: if CONF_ADDRESS in conf:
add(pca9685.set_address(HexIntLiteral(conf[CONF_ADDRESS]))) add(pca9685.set_address(HexIntLiteral(conf[CONF_ADDRESS])))
if CONF_PHASE_BALANCER in conf:
phase_balancer = RawExpression(u'PCA9685_PhaseBalancer_{}'.format(
conf[CONF_PHASE_BALANCER]))
add(pca9685.set_phase_balancer(phase_balancer))
BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT' BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT'

View file

@ -2,7 +2,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575 from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575
from esphomeyaml.helpers import App, Pvariable from esphomeyaml.helpers import App, Pvariable, esphomelib_ns
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
@ -14,11 +14,14 @@ PCF8574_SCHEMA = vol.Schema({
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA]) CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA])
io_ns = esphomelib_ns.namespace('io')
PCF8574Component = io_ns.PCF8574Component
def to_code(config): def to_code(config):
for conf in config: for conf in config:
rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575]) rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575])
Pvariable('io::PCF8574Component', conf[CONF_ID], rhs) Pvariable(PCF8574Component, conf[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_PCF8574' BUILD_FLAGS = '-DUSE_PCF8574'

View file

@ -3,7 +3,7 @@ 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_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN from esphomeyaml.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN
from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression
POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({ POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
@ -13,12 +13,13 @@ POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({
CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA]) CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA])
PowerSupplyComponent = esphomelib_ns.PowerSupplyComponent
def to_code(config): def to_code(config):
for conf in config: for conf in config:
pin = gpio_output_pin_expression(conf[CONF_PIN]) rhs = App.make_power_supply(gpio_output_pin_expression(conf[CONF_PIN]))
rhs = App.make_power_supply(pin) psu = Pvariable(PowerSupplyComponent, conf[CONF_ID], rhs)
psu = Pvariable('PowerSupplyComponent', conf[CONF_ID], rhs)
if CONF_ENABLE_TIME in conf: if CONF_ENABLE_TIME in conf:
add(psu.set_enable_time(conf[CONF_ENABLE_TIME])) add(psu.set_enable_time(conf[CONF_ENABLE_TIME]))
if CONF_KEEP_ON_TIME in conf: if CONF_KEEP_ON_TIME in conf:

View file

@ -1,13 +1,15 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import automation
from esphomeyaml.const import CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_DEBOUNCE, CONF_DELTA, \ from esphomeyaml.const import CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_DEBOUNCE, CONF_DELTA, \
CONF_EXPIRE_AFTER, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, CONF_FILTER_NAN, \ CONF_EXPIRE_AFTER, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, CONF_FILTER_NAN, \
CONF_FILTER_OUT, CONF_HEARTBEAT, CONF_ICON, CONF_LAMBDA, CONF_MQTT_ID, CONF_MULTIPLY, \ CONF_FILTER_OUT, CONF_HEARTBEAT, CONF_ICON, CONF_ID, CONF_LAMBDA, CONF_MAX, CONF_MIN, \
CONF_NAME, CONF_OFFSET, CONF_OR, CONF_SEND_EVERY, CONF_SLIDING_WINDOW_MOVING_AVERAGE, \ CONF_MQTT_ID, CONF_MULTIPLY, CONF_NAME, CONF_OFFSET, CONF_ON_RAW_VALUE, CONF_ON_VALUE, \
CONF_THROTTLE, CONF_UNIQUE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE CONF_ON_VALUE_RANGE, CONF_OR, CONF_SEND_EVERY, CONF_SLIDING_WINDOW_MOVING_AVERAGE, \
from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \ CONF_THROTTLE, CONF_TRIGGER_ID, CONF_UNIQUE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE
setup_mqtt_component from esphomeyaml.helpers import App, ArrayInitializer, NAN, Pvariable, add, esphomelib_ns, float_, \
process_lambda, setup_mqtt_component, templatable
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
@ -18,91 +20,102 @@ def validate_recursive_filter(value):
return FILTERS_SCHEMA(value) return FILTERS_SCHEMA(value)
FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.Any( FILTER_KEYS = [CONF_OFFSET, CONF_MULTIPLY, CONF_FILTER_OUT, CONF_FILTER_NAN,
vol.Schema({vol.Required(CONF_OFFSET): vol.Coerce(float)}), CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_LAMBDA,
vol.Schema({vol.Required(CONF_MULTIPLY): vol.Coerce(float)}), CONF_THROTTLE, CONF_DELTA, CONF_UNIQUE, CONF_HEARTBEAT, CONF_DEBOUNCE, CONF_OR]
vol.Schema({vol.Required(CONF_FILTER_OUT): vol.Coerce(float)}),
vol.Schema({vol.Required(CONF_FILTER_NAN): None}), FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
vol.Schema({ vol.Optional(CONF_OFFSET): vol.Coerce(float),
vol.Required(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.Schema({ vol.Optional(CONF_MULTIPLY): vol.Coerce(float),
vol.Optional(CONF_FILTER_OUT): vol.Coerce(float),
vol.Optional(CONF_FILTER_NAN): None,
vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.Schema({
vol.Required(CONF_WINDOW_SIZE): cv.positive_not_null_int, vol.Required(CONF_WINDOW_SIZE): cv.positive_not_null_int,
vol.Required(CONF_SEND_EVERY): cv.positive_not_null_int, vol.Required(CONF_SEND_EVERY): cv.positive_not_null_int,
})
}), }),
vol.Schema({ vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): vol.Schema({
vol.Required(CONF_EXPONENTIAL_MOVING_AVERAGE): vol.Schema({
vol.Required(CONF_ALPHA): cv.positive_float, vol.Required(CONF_ALPHA): cv.positive_float,
vol.Required(CONF_SEND_EVERY): cv.positive_not_null_int, vol.Required(CONF_SEND_EVERY): cv.positive_not_null_int,
})
}), }),
vol.Schema({vol.Required(CONF_LAMBDA): cv.string_strict}), vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Schema({vol.Required(CONF_THROTTLE): cv.positive_time_period_milliseconds}), vol.Optional(CONF_THROTTLE): cv.positive_time_period_milliseconds,
vol.Schema({vol.Required(CONF_DELTA): vol.Coerce(float)}), vol.Optional(CONF_DELTA): vol.Coerce(float),
vol.Schema({vol.Required(CONF_UNIQUE): None}), vol.Optional(CONF_UNIQUE): None,
vol.Schema({vol.Required(CONF_HEARTBEAT): cv.positive_time_period_milliseconds}), vol.Optional(CONF_HEARTBEAT): cv.positive_time_period_milliseconds,
vol.Schema({vol.Required(CONF_DEBOUNCE): cv.positive_time_period_milliseconds}), vol.Optional(CONF_DEBOUNCE): cv.positive_time_period_milliseconds,
vol.Schema({vol.Required(CONF_OR): validate_recursive_filter}), vol.Optional(CONF_OR): validate_recursive_filter,
)]) }, cv.has_at_exactly_one_key(*FILTER_KEYS))])
MQTT_SENSOR_SCHEMA = vol.Schema({ SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
cv.GenerateID('mqtt_sensor', CONF_MQTT_ID): cv.register_variable_id,
cv.GenerateID('sensor'): cv.register_variable_id,
vol.Required(CONF_NAME): cv.string, vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict, vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
vol.Optional(CONF_ICON): cv.icon, vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int), vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int),
vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period_milliseconds), vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period_milliseconds),
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA vol.Optional(CONF_FILTERS): FILTERS_SCHEMA,
}) vol.Optional(CONF_ON_VALUE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]),
vol.Optional(CONF_ON_RAW_VALUE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA]),
MQTT_SENSOR_ID_SCHEMA = MQTT_SENSOR_SCHEMA.extend({ vol.Optional(CONF_ON_VALUE_RANGE): vol.All(cv.ensure_list, [vol.All(
cv.GenerateID('mqtt_sensor', CONF_MQTT_ID): cv.register_variable_id, automation.AUTOMATION_SCHEMA.extend({
vol.Optional(CONF_MIN): vol.Coerce(float),
vol.Optional(CONF_MAX): vol.Coerce(float),
}), cv.has_at_least_one_key(CONF_MIN, CONF_MAX))]),
}) })
# pylint: disable=invalid-name # pylint: disable=invalid-name
OffsetFilter = MockObj('new sensor::OffsetFilter') sensor_ns = esphomelib_ns.namespace('sensor')
MultiplyFilter = MockObj('new sensor::MultiplyFilter') Sensor = sensor_ns.Sensor
FilterOutValueFilter = MockObj('new sensor::FilterOutValueFilter') MQTTSensorComponent = sensor_ns.MQTTSensorComponent
FilterOutNANFilter = MockObj('new sensor::FilterOutNANFilter') OffsetFilter = sensor_ns.OffsetFilter
SlidingWindowMovingAverageFilter = MockObj('new sensor::SlidingWindowMovingAverageFilter') MultiplyFilter = sensor_ns.MultiplyFilter
ExponentialMovingAverageFilter = MockObj('new sensor::ExponentialMovingAverageFilter') FilterOutValueFilter = sensor_ns.FilterOutValueFilter
LambdaFilter = MockObj('new sensor::LambdaFilter') FilterOutNANFilter = sensor_ns.FilterOutNANFilter
ThrottleFilter = MockObj('new sensor::ThrottleFilter') SlidingWindowMovingAverageFilter = sensor_ns.SlidingWindowMovingAverageFilter
DeltaFilter = MockObj('new sensor::DeltaFilter') ExponentialMovingAverageFilter = sensor_ns.ExponentialMovingAverageFilter
OrFilter = MockObj('new sensor::OrFilter') LambdaFilter = sensor_ns.LambdaFilter
HeartbeatFilter = MockObj('new sensor::HeartbeatFilter') ThrottleFilter = sensor_ns.ThrottleFilter
DebounceFilter = MockObj('new sensor::DebounceFilter') DeltaFilter = sensor_ns.DeltaFilter
UniqueFilter = MockObj('new sensor::UniqueFilter') OrFilter = sensor_ns.OrFilter
HeartbeatFilter = sensor_ns.HeartbeatFilter
DebounceFilter = sensor_ns.DebounceFilter
UniqueFilter = sensor_ns.UniqueFilter
SensorValueTrigger = sensor_ns.SensorValueTrigger
RawSensorValueTrigger = sensor_ns.RawSensorValueTrigger
ValueRangeTrigger = sensor_ns.ValueRangeTrigger
def setup_filter(config): def setup_filter(config):
if CONF_OFFSET in config: if CONF_OFFSET in config:
return OffsetFilter(config[CONF_OFFSET]) return OffsetFilter.new(config[CONF_OFFSET])
if CONF_MULTIPLY in config: if CONF_MULTIPLY in config:
return MultiplyFilter(config[CONF_MULTIPLY]) return MultiplyFilter.new(config[CONF_MULTIPLY])
if CONF_FILTER_OUT in config: if CONF_FILTER_OUT in config:
return FilterOutValueFilter(config[CONF_FILTER_OUT]) return FilterOutValueFilter.new(config[CONF_FILTER_OUT])
if CONF_FILTER_NAN in config: if CONF_FILTER_NAN in config:
return FilterOutNANFilter() return FilterOutNANFilter()
if CONF_SLIDING_WINDOW_MOVING_AVERAGE in config: if CONF_SLIDING_WINDOW_MOVING_AVERAGE in config:
conf = config[CONF_SLIDING_WINDOW_MOVING_AVERAGE] conf = config[CONF_SLIDING_WINDOW_MOVING_AVERAGE]
return SlidingWindowMovingAverageFilter(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY]) return SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY])
if CONF_EXPONENTIAL_MOVING_AVERAGE in config: if CONF_EXPONENTIAL_MOVING_AVERAGE in config:
conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE] conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE]
return ExponentialMovingAverageFilter(conf[CONF_ALPHA], conf[CONF_SEND_EVERY]) return ExponentialMovingAverageFilter.new(conf[CONF_ALPHA], conf[CONF_SEND_EVERY])
if CONF_LAMBDA in config: if CONF_LAMBDA in config:
s = u'[](float x) -> Optional<float> {{ return {}; }}'.format(config[CONF_LAMBDA]) return LambdaFilter.new(process_lambda(config[CONF_LAMBDA], [(float_, 'x')]))
return LambdaFilter(RawExpression(s))
if CONF_THROTTLE in config: if CONF_THROTTLE in config:
return ThrottleFilter(config[CONF_THROTTLE]) return ThrottleFilter.new(config[CONF_THROTTLE])
if CONF_DELTA in config: if CONF_DELTA in config:
return DeltaFilter(config[CONF_DELTA]) return DeltaFilter.new(config[CONF_DELTA])
if CONF_OR in config: if CONF_OR in config:
return OrFilter(setup_filters(config[CONF_OR])) return OrFilter.new(setup_filters(config[CONF_OR]))
if CONF_HEARTBEAT in config: if CONF_HEARTBEAT in config:
return App.register_component(HeartbeatFilter(config[CONF_HEARTBEAT])) return App.register_component(HeartbeatFilter.new(config[CONF_HEARTBEAT]))
if CONF_DEBOUNCE in config: if CONF_DEBOUNCE in config:
return App.register_component(DebounceFilter(config[CONF_DEBOUNCE])) return App.register_component(DebounceFilter.new(config[CONF_DEBOUNCE]))
if CONF_UNIQUE in config: if CONF_UNIQUE in config:
return UniqueFilter() return UniqueFilter.new()
raise ValueError(u"Filter unsupported: {}".format(config)) raise ValueError(u"Filter unsupported: {}".format(config))
@ -110,31 +123,54 @@ def setup_filters(config):
return ArrayInitializer(*[setup_filter(x) for x in config]) return ArrayInitializer(*[setup_filter(x) for x in config])
def setup_mqtt_sensor_component(obj, config): def setup_sensor_core_(sensor_var, mqtt_var, config):
if CONF_UNIT_OF_MEASUREMENT in config:
add(sensor_var.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
if CONF_ICON in config:
add(sensor_var.set_icon(config[CONF_ICON]))
if CONF_ACCURACY_DECIMALS in config:
add(sensor_var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
if CONF_FILTERS in config:
add(sensor_var.set_filters(setup_filters(config[CONF_FILTERS])))
for conf in config.get(CONF_ON_VALUE, []):
rhs = sensor_var.make_value_trigger()
trigger = Pvariable(SensorValueTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, float_, conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
rhs = sensor_var.make_raw_value_trigger()
trigger = Pvariable(RawSensorValueTrigger, conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, float_, conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
rhs = sensor_var.make_value_range_trigger()
trigger = Pvariable(ValueRangeTrigger, conf[CONF_TRIGGER_ID], rhs)
if CONF_MIN in conf:
trigger.set_min(templatable(conf[CONF_MIN], float_, float_))
if CONF_MAX in conf:
trigger.set_max(templatable(conf[CONF_MAX], float_, float_))
automation.build_automation(trigger, float_, conf)
if CONF_EXPIRE_AFTER in config: if CONF_EXPIRE_AFTER in config:
if config[CONF_EXPIRE_AFTER] is None: if config[CONF_EXPIRE_AFTER] is None:
add(obj.disable_expire_after()) add(mqtt_var.disable_expire_after())
else: else:
add(obj.set_expire_after(config[CONF_EXPIRE_AFTER])) add(mqtt_var.set_expire_after(config[CONF_EXPIRE_AFTER]))
setup_mqtt_component(obj, config) setup_mqtt_component(mqtt_var, config)
def setup_sensor(obj, config): def setup_sensor(sensor_obj, mqtt_obj, config):
if CONF_UNIT_OF_MEASUREMENT in config: sensor_var = Pvariable(Sensor, config[CONF_ID], sensor_obj, has_side_effects=False)
add(obj.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT])) mqtt_var = Pvariable(MQTTSensorComponent, config[CONF_MQTT_ID], mqtt_obj,
if CONF_ICON in config: has_side_effects=False)
add(obj.set_icon(config[CONF_ICON])) setup_sensor_core_(sensor_var, mqtt_var, config)
if CONF_ACCURACY_DECIMALS in config:
add(obj.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
if CONF_FILTERS in config:
add(obj.set_filters(setup_filters(config[CONF_FILTERS])))
def register_sensor(var, config): def register_sensor(var, config):
setup_sensor(var, config) sensor_var = Pvariable(Sensor, config[CONF_ID], var, has_side_effects=True)
rhs = App.register_sensor(var) rhs = App.register_sensor(sensor_var)
mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_MQTT_ID], rhs) mqtt_var = Pvariable(MQTTSensorComponent, config[CONF_MQTT_ID], rhs,
setup_mqtt_sensor_component(mqtt_sensor, config) has_side_effects=True)
setup_sensor_core_(sensor_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_SENSOR' BUILD_FLAGS = '-DUSE_SENSOR'

View file

@ -3,37 +3,35 @@ 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_ATTENUATION, CONF_ID, CONF_NAME, CONF_PIN, \ from esphomeyaml.const import CONF_ATTENUATION, CONF_MAKE_ID, CONF_NAME, CONF_PIN, \
CONF_UPDATE_INTERVAL CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, RawExpression, add, variable from esphomeyaml.helpers import App, Application, add, global_ns, variable
ATTENUATION_MODES = { ATTENUATION_MODES = {
'0db': 'ADC_0db', '0db': global_ns.ADC_0db,
'2.5db': 'ADC_2_5db', '2.5db': global_ns.ADC_2_5db,
'6db': 'ADC_6db', '6db': global_ns.ADC_6db,
'11db': 'ADC_11db', '11db': global_ns.ADC_11db,
} }
ATTENUATION_MODE_SCHEMA = vol.Any(*list(ATTENUATION_MODES.keys()))
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('adc'): cv.register_variable_id, cv.GenerateID('adc', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN): pins.analog_pin, vol.Required(CONF_PIN): pins.analog_pin,
vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, ATTENUATION_MODE_SCHEMA), vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, cv.one_of(*ATTENUATION_MODES)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
MakeADCSensor = Application.MakeADCSensor
def to_code(config): def to_code(config):
rhs = App.make_adc_sensor(config[CONF_NAME], config[CONF_PIN], rhs = App.make_adc_sensor(config[CONF_NAME], config[CONF_PIN],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make = variable('Application::MakeADCSensor', config[CONF_ID], rhs) make = variable(MakeADCSensor, config[CONF_MAKE_ID], rhs)
adc = make.Padc adc = make.Padc
if CONF_ATTENUATION in config: if CONF_ATTENUATION in config:
attenuation = ATTENUATION_MODES[config[CONF_ATTENUATION]] add(adc.set_attenuation(ATTENUATION_MODES[config[CONF_ATTENUATION]]))
add(adc.set_attenuation(RawExpression(attenuation))) sensor.setup_sensor(make.Padc, make.Pmqtt, config)
sensor.setup_sensor(adc, config)
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_ADC_SENSOR' BUILD_FLAGS = '-DUSE_ADC_SENSOR'

View file

@ -2,30 +2,31 @@ 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_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL, \ from esphomeyaml.components.ads1115 import ADS1115Component
CONF_NAME, CONF_ID from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_NAME, \
from esphomeyaml.helpers import RawExpression, get_variable, Pvariable CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import get_variable
DEPENDENCIES = ['ads1115'] DEPENDENCIES = ['ads1115']
MUX = { MUX = {
'A0_A1': 'sensor::ADS1115_MULTIPLEXER_P0_N1', 'A0_A1': sensor.sensor_ns.ADS1115_MULTIPLEXER_P0_N1,
'A0_A3': 'sensor::ADS1115_MULTIPLEXER_P0_N3', 'A0_A3': sensor.sensor_ns.ADS1115_MULTIPLEXER_P0_N3,
'A1_A3': 'sensor::ADS1115_MULTIPLEXER_P1_N3', 'A1_A3': sensor.sensor_ns.ADS1115_MULTIPLEXER_P1_N3,
'A2_A3': 'sensor::ADS1115_MULTIPLEXER_P2_N3', 'A2_A3': sensor.sensor_ns.ADS1115_MULTIPLEXER_P2_N3,
'A0_GND': 'sensor::ADS1115_MULTIPLEXER_P0_NG', 'A0_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P0_NG,
'A1_GND': 'sensor::ADS1115_MULTIPLEXER_P1_NG', 'A1_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P1_NG,
'A2_GND': 'sensor::ADS1115_MULTIPLEXER_P2_NG', 'A2_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P2_NG,
'A3_GND': 'sensor::ADS1115_MULTIPLEXER_P3_NG', 'A3_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P3_NG,
} }
GAIN = { GAIN = {
'6.144': 'sensor::ADS1115_GAIN_6P144', '6.144': sensor.sensor_ns.ADS1115_GAIN_6P144,
'4.096': 'sensor::ADS1115_GAIN_6P096', '4.096': sensor.sensor_ns.ADS1115_GAIN_6P096,
'2.048': 'sensor::ADS1115_GAIN_2P048', '2.048': sensor.sensor_ns.ADS1115_GAIN_2P048,
'1.024': 'sensor::ADS1115_GAIN_1P024', '1.024': sensor.sensor_ns.ADS1115_GAIN_1P024,
'0.512': 'sensor::ADS1115_GAIN_0P512', '0.512': sensor.sensor_ns.ADS1115_GAIN_0P512,
'0.256': 'sensor::ADS1115_GAIN_0P256', '0.256': sensor.sensor_ns.ADS1115_GAIN_0P256,
} }
@ -42,21 +43,20 @@ def validate_gain(value):
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('ads1115_sensor'): cv.register_variable_id, cv.GenerateID('ads1115_sensor'): cv.register_variable_id,
vol.Required(CONF_MULTIPLEXER): vol.All(vol.Upper, vol.Any(*list(MUX.keys()))), vol.Required(CONF_MULTIPLEXER): vol.All(vol.Upper, cv.one_of(*MUX)),
vol.Required(CONF_GAIN): validate_gain, vol.Required(CONF_GAIN): validate_gain,
vol.Optional(CONF_ADS1115_ID): cv.variable_id, vol.Optional(CONF_ADS1115_ID): cv.variable_id,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.MQTT_SENSOR_ID_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
def to_code(config): def to_code(config):
hub = get_variable(config.get(CONF_ADS1115_ID), u'sensor::ADS1115Component') hub = get_variable(config.get(CONF_ADS1115_ID), ADS1115Component)
mux = RawExpression(MUX[config[CONF_MULTIPLEXER]]) mux = MUX[config[CONF_MULTIPLEXER]]
gain = RawExpression(GAIN[config[CONF_GAIN]]) gain = GAIN[config[CONF_GAIN]]
rhs = hub.get_sensor(config[CONF_NAME], mux, gain, config.get(CONF_UPDATE_INTERVAL)) rhs = hub.get_sensor(config[CONF_NAME], mux, gain, config.get(CONF_UPDATE_INTERVAL))
sensor_ = Pvariable('sensor::ADS1115Sensor', config[CONF_ID], rhs) sensor.register_sensor(rhs, config)
sensor.register_sensor(sensor_, config)
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR' BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'

View file

@ -2,36 +2,36 @@ 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_ADDRESS, CONF_ID, CONF_NAME, CONF_RESOLUTION, \ from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_RESOLUTION, \
CONF_UPDATE_INTERVAL CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, RawExpression, add, variable from esphomeyaml.helpers import App, Application, add, variable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
BH1750_RESOLUTIONS = { BH1750_RESOLUTIONS = {
4.0: 'sensor::BH1750_RESOLUTION_4P0_LX', 4.0: sensor.sensor_ns.BH1750_RESOLUTION_4P0_LX,
1.0: 'sensor::BH1750_RESOLUTION_1P0_LX', 1.0: sensor.sensor_ns.BH1750_RESOLUTION_1P0_LX,
0.5: 'sensor::BH1750_RESOLUTION_0P5_LX', 0.5: sensor.sensor_ns.BH1750_RESOLUTION_0P5_LX,
} }
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('bh1750_sensor'): cv.register_variable_id, cv.GenerateID('bh1750_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_ADDRESS, default=0x23): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x23): cv.i2c_address,
vol.Optional(CONF_RESOLUTION): vol.All(cv.positive_float, vol.Any(*BH1750_RESOLUTIONS)), vol.Optional(CONF_RESOLUTION): vol.All(cv.positive_float, cv.one_of(*BH1750_RESOLUTIONS)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
MakeBH1750Sensor = Application.MakeBH1750Sensor
def to_code(config): def to_code(config):
rhs = App.make_bh1750_sensor(config[CONF_NAME], config[CONF_ADDRESS], rhs = App.make_bh1750_sensor(config[CONF_NAME], config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make_bh1750 = variable('Application::MakeBH1750Sensor', config[CONF_ID], rhs) make_bh1750 = variable(MakeBH1750Sensor, config[CONF_MAKE_ID], rhs)
bh1750 = make_bh1750.Pbh1750 bh1750 = make_bh1750.Pbh1750
if CONF_RESOLUTION in config: if CONF_RESOLUTION in config:
constant = BH1750_RESOLUTIONS[config[CONF_RESOLUTION]] add(bh1750.set_resolution(BH1750_RESOLUTIONS[config[CONF_RESOLUTION]]))
add(bh1750.set_resolution(RawExpression(constant))) sensor.setup_sensor(bh1750, make_bh1750.Pmqtt, config)
sensor.setup_sensor(bh1750, config)
sensor.setup_mqtt_sensor_component(make_bh1750.Pmqtt, config)
BUILD_FLAGS = '-DUSE_BH1750' BUILD_FLAGS = '-DUSE_BH1750'

View file

@ -2,44 +2,45 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_IIR_FILTER, CONF_MAKE_ID, \
from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_NAME, \ CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL from esphomeyaml.helpers import App, Application, add, variable
from esphomeyaml.helpers import App, RawExpression, add, variable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
OVERSAMPLING_OPTIONS = { OVERSAMPLING_OPTIONS = {
'NONE': 'sensor::BME280_OVERSAMPLING_NONE', 'NONE': sensor.sensor_ns.BME280_OVERSAMPLING_NONE,
'1X': 'sensor::BME280_OVERSAMPLING_1X', '1X': sensor.sensor_ns.BME280_OVERSAMPLING_1X,
'2X': 'sensor::BME280_OVERSAMPLING_2X', '2X': sensor.sensor_ns.BME280_OVERSAMPLING_2X,
'4X': 'sensor::BME280_OVERSAMPLING_4X', '4X': sensor.sensor_ns.BME280_OVERSAMPLING_4X,
'8X': 'sensor::BME280_OVERSAMPLING_8X', '8X': sensor.sensor_ns.BME280_OVERSAMPLING_8X,
'16X': 'sensor::BME280_OVERSAMPLING_16X', '16X': sensor.sensor_ns.BME280_OVERSAMPLING_16X,
} }
IIR_FILTER_OPTIONS = { IIR_FILTER_OPTIONS = {
'OFF': 'sensor::BME280_IIR_FILTER_OFF', 'OFF': sensor.sensor_ns.BME280_IIR_FILTER_OFF,
'2X': 'sensor::BME280_IIR_FILTER_2X', '2X': sensor.sensor_ns.BME280_IIR_FILTER_2X,
'4X': 'sensor::BME280_IIR_FILTER_4X', '4X': sensor.sensor_ns.BME280_IIR_FILTER_4X,
'8X': 'sensor::BME280_IIR_FILTER_8X', '8X': sensor.sensor_ns.BME280_IIR_FILTER_8X,
'16X': 'sensor::BME280_IIR_FILTER_16X', '16X': sensor.sensor_ns.BME280_IIR_FILTER_16X,
} }
BME280_OVERSAMPLING_SENSOR_SCHEMA = MQTT_SENSOR_SCHEMA.extend({ BME280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, vol.Any(*OVERSAMPLING_OPTIONS)), vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)),
}) })
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('bme280'): cv.register_variable_id, cv.GenerateID('bme280', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): BME280_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): BME280_OVERSAMPLING_SENSOR_SCHEMA,
vol.Required(CONF_PRESSURE): BME280_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_PRESSURE): BME280_OVERSAMPLING_SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): BME280_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): BME280_OVERSAMPLING_SENSOR_SCHEMA,
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, vol.Any(*IIR_FILTER_OPTIONS)), 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, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeBME280Sensor = Application.MakeBME280Sensor
def to_code(config): def to_code(config):
rhs = App.make_bme280_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_bme280_sensor(config[CONF_TEMPERATURE][CONF_NAME],
@ -47,29 +48,27 @@ def to_code(config):
config[CONF_HUMIDITY][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME],
config[CONF_ADDRESS], config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make = variable('Application::MakeBME280Sensor', config[CONF_ID], rhs) make = variable(MakeBME280Sensor, config[CONF_MAKE_ID], rhs)
bme280 = make.Pbme280 bme280 = make.Pbme280
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]: if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]] constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
add(bme280.set_temperature_oversampling(RawExpression(constant))) add(bme280.set_temperature_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_PRESSURE]: if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]] constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
add(bme280.set_pressure_oversampling(RawExpression(constant))) add(bme280.set_pressure_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_HUMIDITY]: if CONF_OVERSAMPLING in config[CONF_HUMIDITY]:
constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]] constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]]
add(bme280.set_humidity_oversampling(RawExpression(constant))) add(bme280.set_humidity_oversampling(constant))
if CONF_IIR_FILTER in config: if CONF_IIR_FILTER in config:
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]] constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
add(bme280.set_iir_filter(RawExpression(constant))) add(bme280.set_iir_filter(constant))
sensor.setup_sensor(bme280.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) sensor.setup_sensor(bme280.Pget_temperature_sensor(), make.Pmqtt_temperature,
sensor.setup_mqtt_sensor_component(make.Pmqtt_temperature, config[CONF_TEMPERATURE]) config[CONF_TEMPERATURE])
sensor.setup_sensor(bme280.Pget_pressure_sensor(), make.Pmqtt_pressure,
sensor.setup_sensor(bme280.Pget_pressure_sensor(), config[CONF_PRESSURE]) config[CONF_PRESSURE])
sensor.setup_mqtt_sensor_component(make.Pmqtt_pressure, config[CONF_PRESSURE]) sensor.setup_sensor(bme280.Pget_humidity_sensor(), make.Pmqtt_humidity,
config[CONF_HUMIDITY])
sensor.setup_sensor(bme280.Pget_humidity_sensor(), config[CONF_HUMIDITY])
sensor.setup_mqtt_sensor_component(make.Pmqtt_humidity, config[CONF_HUMIDITY])
BUILD_FLAGS = '-DUSE_BME280' BUILD_FLAGS = '-DUSE_BME280'

View file

@ -2,49 +2,51 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_ADDRESS, CONF_GAS_RESISTANCE, CONF_HUMIDITY, CONF_IIR_FILTER, \
from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_NAME, \ CONF_MAKE_ID, CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, \
CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL, CONF_GAS_RESISTANCE CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, RawExpression, add, variable from esphomeyaml.helpers import App, Application, add, variable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
OVERSAMPLING_OPTIONS = { OVERSAMPLING_OPTIONS = {
'NONE': 'sensor::BME680_OVERSAMPLING_NONE', 'NONE': sensor.sensor_ns.BME680_OVERSAMPLING_NONE,
'1X': 'sensor::BME680_OVERSAMPLING_1X', '1X': sensor.sensor_ns.BME680_OVERSAMPLING_1X,
'2X': 'sensor::BME680_OVERSAMPLING_2X', '2X': sensor.sensor_ns.BME680_OVERSAMPLING_2X,
'4X': 'sensor::BME680_OVERSAMPLING_4X', '4X': sensor.sensor_ns.BME680_OVERSAMPLING_4X,
'8X': 'sensor::BME680_OVERSAMPLING_8X', '8X': sensor.sensor_ns.BME680_OVERSAMPLING_8X,
'16X': 'sensor::BME680_OVERSAMPLING_16X', '16X': sensor.sensor_ns.BME680_OVERSAMPLING_16X,
} }
IIR_FILTER_OPTIONS = { IIR_FILTER_OPTIONS = {
'OFF': 'sensor::BME680_IIR_FILTER_OFF', 'OFF': sensor.sensor_ns.BME680_IIR_FILTER_OFF,
'1X': 'sensor::BME680_IIR_FILTER_1X', '1X': sensor.sensor_ns.BME680_IIR_FILTER_1X,
'3X': 'sensor::BME680_IIR_FILTER_3X', '3X': sensor.sensor_ns.BME680_IIR_FILTER_3X,
'7X': 'sensor::BME680_IIR_FILTER_7X', '7X': sensor.sensor_ns.BME680_IIR_FILTER_7X,
'15X': 'sensor::BME680_IIR_FILTER_15X', '15X': sensor.sensor_ns.BME680_IIR_FILTER_15X,
'31X': 'sensor::BME680_IIR_FILTER_31X', '31X': sensor.sensor_ns.BME680_IIR_FILTER_31X,
'63X': 'sensor::BME680_IIR_FILTER_63X', '63X': sensor.sensor_ns.BME680_IIR_FILTER_63X,
'127X': 'sensor::BME680_IIR_FILTER_127X', '127X': sensor.sensor_ns.BME680_IIR_FILTER_127X,
} }
BME680_OVERSAMPLING_SENSOR_SCHEMA = MQTT_SENSOR_SCHEMA.extend({ BME680_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, vol.Any(*OVERSAMPLING_OPTIONS)), vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)),
}) })
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('bme680'): cv.register_variable_id, cv.GenerateID('bme680', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_ADDRESS, default=0x76): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x76): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): BME680_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): BME680_OVERSAMPLING_SENSOR_SCHEMA,
vol.Required(CONF_PRESSURE): BME680_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_PRESSURE): BME680_OVERSAMPLING_SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): BME680_OVERSAMPLING_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): BME680_OVERSAMPLING_SENSOR_SCHEMA,
vol.Required(CONF_GAS_RESISTANCE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_GAS_RESISTANCE): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, vol.Any(*IIR_FILTER_OPTIONS)), vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, cv.one_of(*IIR_FILTER_OPTIONS)),
# TODO: Heater # TODO: Heater
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeBME680Sensor = Application.MakeBME680Sensor
def to_code(config): def to_code(config):
rhs = App.make_bme680_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_bme680_sensor(config[CONF_TEMPERATURE][CONF_NAME],
@ -53,32 +55,29 @@ def to_code(config):
config[CONF_GAS_RESISTANCE][CONF_NAME], config[CONF_GAS_RESISTANCE][CONF_NAME],
config[CONF_ADDRESS], config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make = variable('Application::MakeBME680Sensor', config[CONF_ID], rhs) make = variable(MakeBME680Sensor, config[CONF_MAKE_ID], rhs)
bme680 = make.Pbme680 bme680 = make.Pbme680
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]: if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]] constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
add(bme680.set_temperature_oversampling(RawExpression(constant))) add(bme680.set_temperature_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_PRESSURE]: if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]] constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
add(bme680.set_pressure_oversampling(RawExpression(constant))) add(bme680.set_pressure_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_HUMIDITY]: if CONF_OVERSAMPLING in config[CONF_HUMIDITY]:
constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]] constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]]
add(bme680.set_humidity_oversampling(RawExpression(constant))) add(bme680.set_humidity_oversampling(constant))
if CONF_IIR_FILTER in config: if CONF_IIR_FILTER in config:
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]] constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
add(bme680.set_iir_filter(RawExpression(constant))) add(bme680.set_iir_filter(constant))
sensor.setup_sensor(bme680.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) sensor.setup_sensor(bme680.Pget_temperature_sensor(), make.Pmqtt_temperature,
sensor.setup_mqtt_sensor_component(make.Pmqtt_temperature, config[CONF_TEMPERATURE]) config[CONF_TEMPERATURE])
sensor.setup_sensor(bme680.Pget_pressure_sensor(), make.Pmqtt_pressure,
sensor.setup_sensor(bme680.Pget_pressure_sensor(), config[CONF_PRESSURE]) config[CONF_PRESSURE])
sensor.setup_mqtt_sensor_component(make.Pmqtt_pressure, config[CONF_PRESSURE]) sensor.setup_sensor(bme680.Pget_humidity_sensor(), make.Pmqtt_humidity,
config[CONF_HUMIDITY])
sensor.setup_sensor(bme680.Pget_humidity_sensor(), config[CONF_HUMIDITY]) sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), make.Pmqtt_gas_resistance,
sensor.setup_mqtt_sensor_component(make.Pmqtt_humidity, config[CONF_HUMIDITY]) config[CONF_GAS_RESISTANCE])
sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), config[CONF_GAS_RESISTANCE])
sensor.setup_mqtt_sensor_component(make.Pmqtt_gas_resistance, config[CONF_GAS_RESISTANCE])
BUILD_FLAGS = '-DUSE_BME680' BUILD_FLAGS = '-DUSE_BME680'

View file

@ -2,33 +2,35 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_PRESSURE, \
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_NAME, \ CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL from esphomeyaml.helpers import App, HexIntLiteral, add, variable, Application
from esphomeyaml.helpers import App, HexIntLiteral, add, variable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('bmp085_sensor'): cv.register_variable_id, cv.GenerateID('bmp085_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Required(CONF_PRESSURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_PRESSURE): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_ADDRESS): cv.i2c_address, vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeBMP085Sensor = Application.MakeBMP085Sensor
def to_code(config): def to_code(config):
rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME], config[CONF_PRESSURE][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
bmp = variable('Application::MakeBMP085Sensor', config[CONF_ID], rhs) bmp = variable(MakeBMP085Sensor, config[CONF_MAKE_ID], rhs)
if CONF_ADDRESS in config: if CONF_ADDRESS in config:
add(bmp.Pbmp.set_address(HexIntLiteral(config[CONF_ADDRESS]))) add(bmp.Pbmp.set_address(HexIntLiteral(config[CONF_ADDRESS])))
sensor.setup_sensor(bmp.Pbmp.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(bmp.Pmqtt_temperature, config[CONF_TEMPERATURE]) sensor.setup_sensor(bmp.Pbmp.Pget_temperature_sensor(), bmp.Pmqtt_temperature,
sensor.setup_sensor(bmp.Pbmp.Pget_pressure_sensor(), config[CONF_PRESSURE]) config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(bmp.Pmqtt_pressure, config[CONF_PRESSURE]) sensor.setup_sensor(bmp.Pbmp.Pget_pressure_sensor(), bmp.Pmqtt_pressure,
config[CONF_PRESSURE])
BUILD_FLAGS = '-DUSE_BMP085_SENSOR' BUILD_FLAGS = '-DUSE_BMP085_SENSOR'

View file

@ -2,23 +2,21 @@ 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.components.dallas import DALLAS_COMPONENT_CLASS from esphomeyaml.components.dallas import DallasComponent
from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \ from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \
CONF_RESOLUTION, \ CONF_RESOLUTION, CONF_UPDATE_INTERVAL
CONF_UPDATE_INTERVAL, CONF_ID from esphomeyaml.helpers import HexIntLiteral, get_variable
from esphomeyaml.helpers import HexIntLiteral, get_variable, Pvariable
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('dallas_sensor'): cv.register_variable_id,
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int, vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int, vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
vol.Optional(CONF_DALLAS_ID): cv.variable_id, vol.Optional(CONF_DALLAS_ID): cv.variable_id,
vol.Optional(CONF_RESOLUTION): vol.All(vol.Coerce(int), vol.Range(min=8, max=12)), vol.Optional(CONF_RESOLUTION): vol.All(vol.Coerce(int), vol.Range(min=8, max=12)),
}).extend(sensor.MQTT_SENSOR_ID_SCHEMA.schema), cv.has_at_least_one_key(CONF_ADDRESS, CONF_INDEX)) }).extend(sensor.SENSOR_SCHEMA.schema), cv.has_at_least_one_key(CONF_ADDRESS, CONF_INDEX))
def to_code(config): def to_code(config):
hub = get_variable(config.get(CONF_DALLAS_ID), DALLAS_COMPONENT_CLASS) hub = get_variable(config.get(CONF_DALLAS_ID), DallasComponent)
update_interval = config.get(CONF_UPDATE_INTERVAL) update_interval = config.get(CONF_UPDATE_INTERVAL)
if CONF_RESOLUTION in config and update_interval is None: if CONF_RESOLUTION in config and update_interval is None:
update_interval = 10000 update_interval = 10000
@ -30,8 +28,7 @@ def to_code(config):
else: else:
rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX], rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX],
update_interval, config.get(CONF_RESOLUTION)) update_interval, config.get(CONF_RESOLUTION))
sensor_ = Pvariable('sensor::DallasTemperatureSensor', config[CONF_ID], rhs) sensor.register_sensor(rhs, config)
sensor.register_sensor(sensor_, config)
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR' BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'

View file

@ -2,43 +2,45 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, RawExpression, add, variable, gpio_output_pin_expression from esphomeyaml.helpers import App, Application, add, gpio_output_pin_expression, variable
from esphomeyaml.pins import GPIO_OUTPUT_PIN_SCHEMA from esphomeyaml.pins import GPIO_OUTPUT_PIN_SCHEMA
DHT_MODELS = { DHT_MODELS = {
'AUTO_DETECT': 'sensor::DHT_MODEL_AUTO_DETECT', 'AUTO_DETECT': sensor.sensor_ns.DHT_MODEL_AUTO_DETECT,
'DHT11': 'sensor::DHT_MODEL_DHT11', 'DHT11': sensor.sensor_ns.DHT_MODEL_DHT11,
'DHT22': 'sensor::DHT_MODEL_DHT22', 'DHT22': sensor.sensor_ns.DHT_MODEL_DHT22,
'AM2302': 'sensor::DHT_MODEL_AM2302', 'AM2302': sensor.sensor_ns.DHT_MODEL_AM2302,
'RHT03': 'sensor::DHT_MODEL_RHT03', 'RHT03': sensor.sensor_ns.DHT_MODEL_RHT03,
} }
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('dht_sensor'): cv.register_variable_id, cv.GenerateID('dht_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN): GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_PIN): GPIO_OUTPUT_PIN_SCHEMA,
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_MODEL): vol.All(vol.Upper, vol.Any(*DHT_MODELS)), vol.Optional(CONF_MODEL): vol.All(vol.Upper, cv.one_of(*DHT_MODELS)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeDHTSensor = Application.MakeDHTSensor
def to_code(config): def to_code(config):
pin = gpio_output_pin_expression(config[CONF_PIN]) pin = gpio_output_pin_expression(config[CONF_PIN])
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME],
pin, config.get(CONF_UPDATE_INTERVAL)) pin, config.get(CONF_UPDATE_INTERVAL))
dht = variable('Application::MakeDHTSensor', config[CONF_ID], rhs) dht = variable(MakeDHTSensor, config[CONF_MAKE_ID], rhs)
if CONF_MODEL in config: if CONF_MODEL in config:
constant = DHT_MODELS[config[CONF_MODEL]] constant = DHT_MODELS[config[CONF_MODEL]]
add(dht.Pdht.set_dht_model(RawExpression(constant))) add(dht.Pdht.set_dht_model(constant))
sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(dht.Pmqtt_temperature, config[CONF_TEMPERATURE]) sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(),
sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), config[CONF_HUMIDITY]) dht.Pmqtt_temperature, config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(dht.Pmqtt_humidity, config[CONF_HUMIDITY]) sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(),
dht.Pmqtt_humidity, config[CONF_HUMIDITY])
BUILD_FLAGS = '-DUSE_DHT_SENSOR' BUILD_FLAGS = '-DUSE_DHT_SENSOR'

View file

@ -2,30 +2,32 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, variable from esphomeyaml.helpers import App, Application, variable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('dht_sensor'): cv.register_variable_id, cv.GenerateID('dht_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeDHT12Sensor = Application.MakeDHT12Sensor
def to_code(config): def to_code(config):
rhs = App.make_dht12_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_dht12_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
dht = variable('Application::MakeDHT12Sensor', config[CONF_ID], rhs) dht = variable(MakeDHT12Sensor, config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(dht.Pmqtt_temperature, config[CONF_TEMPERATURE]) sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), dht.Pmqtt_temperature,
sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), config[CONF_HUMIDITY]) config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(dht.Pmqtt_humidity, config[CONF_HUMIDITY]) sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), dht.Pmqtt_humidity,
config[CONF_HUMIDITY])
BUILD_FLAGS = '-DUSE_DHT12_SENSOR' BUILD_FLAGS = '-DUSE_DHT12_SENSOR'

View file

@ -2,30 +2,32 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, variable from esphomeyaml.helpers import App, variable, Application
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('dht_sensor'): cv.register_variable_id, cv.GenerateID('hdc1080_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeHDC1080Sensor = Application.MakeHDC1080Sensor
def to_code(config): def to_code(config):
rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
hdc1080 = variable('Application::MakeHDC1080Sensor', config[CONF_ID], rhs) hdc1080 = variable(MakeHDC1080Sensor, config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(hdc1080.Phdc1080.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(hdc1080.Pmqtt_temperature, config[CONF_TEMPERATURE]) sensor.setup_sensor(hdc1080.Phdc1080.Pget_temperature_sensor(), hdc1080.Pmqtt_temperature,
sensor.setup_sensor(hdc1080.Phdc1080.Pget_humidity_sensor(), config[CONF_HUMIDITY]) config[CONF_TEMPERATURE])
sensor.setup_mqtt_sensor_component(hdc1080.Pmqtt_humidity, config[CONF_HUMIDITY]) sensor.setup_sensor(hdc1080.Phdc1080.Pget_humidity_sensor(), hdc1080.Pmqtt_humidity,
config[CONF_HUMIDITY])
BUILD_FLAGS = '-DUSE_HDC1080_SENSOR' BUILD_FLAGS = '-DUSE_HDC1080_SENSOR'

View file

@ -2,30 +2,31 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, variable from esphomeyaml.helpers import App, variable, Application
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('htu21d'): cv.register_variable_id, cv.GenerateID('htu21d', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeHTU21DSensor = Application.MakeHTU21DSensor
def to_code(config): def to_code(config):
rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
htu21d = variable('Application::MakeHTU21DSensor', config[CONF_ID], rhs) htu21d = variable(MakeHTU21DSensor, config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(htu21d.Phtu21d.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) sensor.setup_sensor(htu21d.Phtu21d.Pget_temperature_sensor(), htu21d.Pmqtt_temperature,
sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_temperature, config[CONF_TEMPERATURE]) config[CONF_TEMPERATURE])
sensor.setup_sensor(htu21d.Phtu21d.Pget_humidity_sensor(), config[CONF_HUMIDITY]) sensor.setup_sensor(htu21d.Phtu21d.Pget_humidity_sensor(), htu21d.Pmqtt_humidity,
sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_humidity, config[CONF_HUMIDITY]) config[CONF_HUMIDITY])
BUILD_FLAGS = '-DUSE_HTU21D_SENSOR' BUILD_FLAGS = '-DUSE_HTU21D_SENSOR'

View file

@ -0,0 +1,32 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import pins
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN_CLOCK, CONF_PIN_CS, CONF_PIN_MISO, \
CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Application, gpio_input_pin_expression, \
gpio_output_pin_expression, variable
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('max6675', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN_CS): pins.GPIO_OUTPUT_PIN_SCHEMA,
vol.Required(CONF_PIN_CLOCK): pins.GPIO_OUTPUT_PIN_SCHEMA,
vol.Optional(CONF_PIN_MISO): pins.GPIO_INPUT_PIN_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.SENSOR_SCHEMA.schema)
MakeMAX6675Sensor = Application.MakeMAX6675Sensor
def to_code(config):
pin_cs = gpio_output_pin_expression(config[CONF_PIN_CS])
pin_clock = gpio_output_pin_expression(config[CONF_PIN_CLOCK])
pin_miso = gpio_input_pin_expression(config[CONF_PIN_MISO])
rhs = App.make_max6675_sensor(config[CONF_NAME], pin_cs, pin_clock, pin_miso,
config.get(CONF_UPDATE_INTERVAL))
make = variable(MakeMAX6675Sensor, config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(make.Pmax6675, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_MAX6675_SENSOR'

View file

@ -2,8 +2,8 @@ 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.components.sensor import MQTT_SENSOR_ID_SCHEMA from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_MQTT_ID, CONF_NAME, \
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_MQTT_ID, CONF_NAME, CONF_TEMPERATURE, \ CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, Pvariable from esphomeyaml.helpers import App, Pvariable
@ -16,57 +16,63 @@ CONF_GYRO_X = 'gyro_x'
CONF_GYRO_Y = 'gyro_y' CONF_GYRO_Y = 'gyro_y'
CONF_GYRO_Z = 'gyro_z' CONF_GYRO_Z = 'gyro_z'
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('mpu6050'): cv.register_variable_id, cv.GenerateID('mpu6050', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_ADDRESS, default=0x68): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x68): cv.i2c_address,
vol.Optional(CONF_ACCEL_X): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_ACCEL_X): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_ACCEL_Y): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_ACCEL_Y): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_ACCEL_Z): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_ACCEL_Z): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_GYRO_X): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_GYRO_X): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_GYRO_Y): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_GYRO_Y): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_GYRO_Z): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_GYRO_Z): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_TEMPERATURE): MQTT_SENSOR_ID_SCHEMA, vol.Optional(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) }), cv.has_at_least_one_key(CONF_ACCEL_X, CONF_ACCEL_Y, CONF_ACCEL_Z,
CONF_GYRO_X, CONF_GYRO_Y, CONF_GYRO_Z))
MPU6050Component = sensor.sensor_ns.MPU6050Component
MPU6050AccelSensor = sensor.sensor_ns.MPU6050AccelSensor
MPU6050GyroSensor = sensor.sensor_ns.MPU6050GyroSensor
MPU6050TemperatureSensor = sensor.sensor_ns.MPU6050TemperatureSensor
def to_code(config): def to_code(config):
rhs = App.make_mpu6050_sensor(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL)) rhs = App.make_mpu6050_sensor(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL))
mpu = Pvariable('sensor::MPU6050Component', config[CONF_ID], rhs) mpu = Pvariable(MPU6050Component, config[CONF_MAKE_ID], rhs)
if CONF_ACCEL_X in config: if CONF_ACCEL_X in config:
conf = config[CONF_ACCEL_X] conf = config[CONF_ACCEL_X]
rhs = mpu.Pmake_accel_x_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_accel_x_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050AccelSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)
if CONF_ACCEL_Y in config: if CONF_ACCEL_Y in config:
conf = config[CONF_ACCEL_Y] conf = config[CONF_ACCEL_Y]
rhs = mpu.Pmake_accel_y_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_accel_y_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050AccelSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)
if CONF_ACCEL_Z in config: if CONF_ACCEL_Z in config:
conf = config[CONF_ACCEL_Z] conf = config[CONF_ACCEL_Z]
rhs = mpu.Pmake_accel_z_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_accel_z_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050AccelSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050AccelSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)
if CONF_GYRO_X in config: if CONF_GYRO_X in config:
conf = config[CONF_GYRO_X] conf = config[CONF_GYRO_X]
rhs = mpu.Pmake_gyro_x_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_gyro_x_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050GyroSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)
if CONF_GYRO_Y in config: if CONF_GYRO_Y in config:
conf = config[CONF_GYRO_Y] conf = config[CONF_GYRO_Y]
rhs = mpu.Pmake_gyro_y_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_gyro_y_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050GyroSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)
if CONF_GYRO_Z in config: if CONF_GYRO_Z in config:
conf = config[CONF_GYRO_Z] conf = config[CONF_GYRO_Z]
rhs = mpu.Pmake_gyro_z_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_gyro_z_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050GyroSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050GyroSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)
if CONF_TEMPERATURE in config: if CONF_TEMPERATURE in config:
conf = config[CONF_TEMPERATURE] conf = config[CONF_TEMPERATURE]
rhs = mpu.Pmake_temperature_sensor(conf[CONF_NAME]) rhs = mpu.Pmake_temperature_sensor(conf[CONF_NAME])
sensor_ = Pvariable('sensor::MPU6050TemperatureSensor', conf[CONF_MQTT_ID], rhs) sensor_ = Pvariable(MPU6050TemperatureSensor, conf[CONF_MQTT_ID], rhs)
sensor.register_sensor(sensor_, conf) sensor.register_sensor(sensor_, conf)

View file

@ -3,32 +3,32 @@ 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_COUNT_MODE, CONF_FALLING_EDGE, CONF_ID, CONF_INTERNAL_FILTER, \ from esphomeyaml.const import CONF_COUNT_MODE, CONF_FALLING_EDGE, CONF_INTERNAL_FILTER, \
CONF_NAME, CONF_PIN, CONF_PULL_MODE, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL, \ CONF_MAKE_ID, CONF_NAME, CONF_PIN, CONF_PULL_MODE, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL, \
ESP_PLATFORM_ESP32 ESP_PLATFORM_ESP32
from esphomeyaml.helpers import App, RawExpression, add, variable from esphomeyaml.helpers import App, add, global_ns, variable, Application
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
GPIO_PULL_MODES = { GPIO_PULL_MODES = {
'PULLUP': 'GPIO_PULLUP_ONLY', 'PULLUP': global_ns.GPIO_PULLUP_ONLY,
'PULLDOWN': 'GPIO_PULLDOWN_ONLY', 'PULLDOWN': global_ns.GPIO_PULLDOWN_ONLY,
'PULLUP_PULLDOWN': 'GPIO_PULLUP_PULLDOWN', 'PULLUP_PULLDOWN': global_ns.GPIO_PULLUP_PULLDOWN,
'FLOATING': 'GPIO_FLOATING', 'FLOATING': global_ns.GPIO_FLOATING,
} }
GPIO_PULL_MODE_SCHEMA = vol.All(vol.Upper, vol.Any(*list(GPIO_PULL_MODES.keys()))) GPIO_PULL_MODE_SCHEMA = vol.All(vol.Upper, cv.one_of(*GPIO_PULL_MODES))
COUNT_MODES = { COUNT_MODES = {
'DISABLE': 'PCNT_COUNT_DIS', 'DISABLE': global_ns.PCNT_COUNT_DIS,
'INCREMENT': 'PCNT_COUNT_INC', 'INCREMENT': global_ns.PCNT_COUNT_INC,
'DECREMENT': 'PCNT_COUNT_DEC', 'DECREMENT': global_ns.PCNT_COUNT_DEC,
} }
COUNT_MODE_SCHEMA = vol.All(vol.Upper, vol.Any(*list(COUNT_MODES.keys()))) COUNT_MODE_SCHEMA = vol.All(vol.Upper, cv.one_of(COUNT_MODES))
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('pulse_counter'): cv.register_variable_id, cv.GenerateID('pulse_counter', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN): pins.input_pin, vol.Required(CONF_PIN): pins.input_pin,
vol.Optional(CONF_PULL_MODE): GPIO_PULL_MODE_SCHEMA, vol.Optional(CONF_PULL_MODE): GPIO_PULL_MODE_SCHEMA,
vol.Optional(CONF_COUNT_MODE): vol.Schema({ vol.Optional(CONF_COUNT_MODE): vol.Schema({
@ -37,26 +37,27 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
}), }),
vol.Optional(CONF_INTERNAL_FILTER): vol.All(vol.Coerce(int), vol.Range(min=0, max=1023)), vol.Optional(CONF_INTERNAL_FILTER): vol.All(vol.Coerce(int), vol.Range(min=0, max=1023)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
MakePulseCounterSensor = Application.MakePulseCounterSensor
def to_code(config): def to_code(config):
rhs = App.make_pulse_counter_sensor(config[CONF_NAME], config[CONF_PIN], rhs = App.make_pulse_counter_sensor(config[CONF_NAME], config[CONF_PIN],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make = variable('Application::MakePulseCounterSensor', config[CONF_ID], rhs) make = variable(MakePulseCounterSensor, config[CONF_MAKE_ID], rhs)
pcnt = make.Ppcnt pcnt = make.Ppcnt
if CONF_PULL_MODE in config: if CONF_PULL_MODE in config:
pull_mode = GPIO_PULL_MODES[config[CONF_PULL_MODE]] pull_mode = GPIO_PULL_MODES[config[CONF_PULL_MODE]]
add(pcnt.set_pull_mode(RawExpression(pull_mode))) add(pcnt.set_pull_mode(pull_mode))
if CONF_COUNT_MODE in config: if CONF_COUNT_MODE in config:
count_mode = config[CONF_COUNT_MODE] count_mode = config[CONF_COUNT_MODE]
rising_edge = COUNT_MODES[count_mode[CONF_RISING_EDGE]] rising_edge = COUNT_MODES[count_mode[CONF_RISING_EDGE]]
falling_edge = COUNT_MODES[count_mode[CONF_FALLING_EDGE]] falling_edge = COUNT_MODES[count_mode[CONF_FALLING_EDGE]]
add(pcnt.set_edge_mode(RawExpression(rising_edge), RawExpression(falling_edge))) add(pcnt.set_edge_mode(rising_edge, falling_edge))
if CONF_INTERNAL_FILTER in config: if CONF_INTERNAL_FILTER in config:
add(pcnt.set_filter(config[CONF_INTERNAL_FILTER])) add(pcnt.set_filter(config[CONF_INTERNAL_FILTER]))
sensor.setup_sensor(pcnt, config) sensor.setup_sensor(make.Ppcnt, make.Pmqtt, config)
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_PULSE_COUNTER_SENSOR' BUILD_FLAGS = '-DUSE_PULSE_COUNTER_SENSOR'

View file

@ -3,13 +3,13 @@ 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_ID, CONF_NAME, CONF_RESOLUTION from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_RESOLUTION
from esphomeyaml.helpers import App, RawExpression, add, gpio_input_pin_expression, variable from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, variable
RESOLUTIONS = { RESOLUTIONS = {
'1': 'sensor::ROTARY_ENCODER_1_PULSE_PER_CYCLE', '1': sensor.sensor_ns.ROTARY_ENCODER_1_PULSE_PER_CYCLE,
'2': 'sensor::ROTARY_ENCODER_2_PULSES_PER_CYCLE', '2': sensor.sensor_ns.ROTARY_ENCODER_2_PULSES_PER_CYCLE,
'4': 'sensor::ROTARY_ENCODER_4_PULSES_PER_CYCLE', '4': sensor.sensor_ns.ROTARY_ENCODER_4_PULSES_PER_CYCLE,
} }
CONF_PIN_A = 'pin_a' CONF_PIN_A = 'pin_a'
@ -17,28 +17,29 @@ CONF_PIN_B = 'pin_b'
CONF_PIN_RESET = 'pin_reset' CONF_PIN_RESET = 'pin_reset'
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('rotary_encoder'): cv.register_variable_id, cv.GenerateID('rotary_encoder', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN_A): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Required(CONF_PIN_A): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA,
vol.Required(CONF_PIN_B): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Required(CONF_PIN_B): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA,
vol.Optional(CONF_PIN_RESET): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Optional(CONF_PIN_RESET): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA,
vol.Optional(CONF_RESOLUTION): vol.All(cv.string, vol.Any(*RESOLUTIONS)), vol.Optional(CONF_RESOLUTION): vol.All(cv.string, cv.one_of(*RESOLUTIONS)),
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
MakeRotaryEncoderSensor = Application.MakeRotaryEncoderSensor
def to_code(config): def to_code(config):
pin_a = gpio_input_pin_expression(config[CONF_PIN_A]) pin_a = gpio_input_pin_expression(config[CONF_PIN_A])
pin_b = gpio_input_pin_expression(config[CONF_PIN_B]) pin_b = gpio_input_pin_expression(config[CONF_PIN_B])
rhs = App.make_rotary_encoder_sensor(config[CONF_NAME], pin_a, pin_b) rhs = App.make_rotary_encoder_sensor(config[CONF_NAME], pin_a, pin_b)
make = variable('Application::MakeRotaryEncoderSensor', config[CONF_ID], rhs) make = variable(MakeRotaryEncoderSensor, config[CONF_MAKE_ID], rhs)
encoder = make.Protary_encoder encoder = make.Protary_encoder
if CONF_PIN_RESET in config: if CONF_PIN_RESET in config:
pin_i = gpio_input_pin_expression(config[CONF_PIN_RESET]) pin_i = gpio_input_pin_expression(config[CONF_PIN_RESET])
add(encoder.set_reset_pin(pin_i)) add(encoder.set_reset_pin(pin_i))
if CONF_RESOLUTION in config: if CONF_RESOLUTION in config:
resolution = RESOLUTIONS[config[CONF_RESOLUTION]] resolution = RESOLUTIONS[config[CONF_RESOLUTION]]
add(encoder.set_resolution(RawExpression(resolution))) add(encoder.set_resolution(resolution))
sensor.setup_sensor(encoder, config) sensor.setup_sensor(encoder, make.Pmqtt, config)
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_ROTARY_ENCODER_SENSOR' BUILD_FLAGS = '-DUSE_ROTARY_ENCODER_SENSOR'

View file

@ -2,44 +2,43 @@ 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.components.sensor import MQTT_SENSOR_SCHEMA from esphomeyaml.const import CONF_ACCURACY, CONF_ADDRESS, CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, \
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \ CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
CONF_UPDATE_INTERVAL, CONF_ADDRESS, CONF_ACCURACY from esphomeyaml.helpers import App, Application, add, variable
from esphomeyaml.helpers import App, variable, RawExpression, add
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
SHT_ACCURACIES = { SHT_ACCURACIES = {
'LOW': 'sensor::SHT3XD_ACCURACY_LOW', 'LOW': sensor.sensor_ns.SHT3XD_ACCURACY_LOW,
'MEDIUM': 'sensor::SHT3XD_ACCURACY_MEDIUM', 'MEDIUM': sensor.sensor_ns.SHT3XD_ACCURACY_MEDIUM,
'HIGH': 'sensor::SHT3XD_ACCURACY_HIGH', 'HIGH': sensor.sensor_ns.SHT3XD_ACCURACY_HIGH,
} }
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('sht3xd'): cv.register_variable_id, cv.GenerateID('sht3xd', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA, vol.Required(CONF_TEMPERATURE): sensor.SENSOR_SCHEMA,
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA, vol.Required(CONF_HUMIDITY): sensor.SENSOR_SCHEMA,
vol.Optional(CONF_ADDRESS, default=0x44): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x44): cv.i2c_address,
vol.Optional(CONF_ACCURACY): vol.All(vol.Upper, vol.Any(*SHT_ACCURACIES)), vol.Optional(CONF_ACCURACY): vol.All(vol.Upper, cv.one_of(*SHT_ACCURACIES)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}) })
MakeSHT3XDSensor = Application.MakeSHT3XDSensor
def to_code(config): def to_code(config):
rhs = App.make_sht3xd_sensor(config[CONF_TEMPERATURE][CONF_NAME], rhs = App.make_sht3xd_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME], config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
sht3xd = variable('Application::MakeSHT3XDSensor', config[CONF_ID], rhs) sht3xd = variable(MakeSHT3XDSensor, config[CONF_MAKE_ID], rhs)
if CONF_ACCURACY in config: if CONF_ACCURACY in config:
constant = RawExpression(SHT_ACCURACIES[config[CONF_ACCURACY]]) add(sht3xd.Psht3xd.set_accuracy(SHT_ACCURACIES[config[CONF_ACCURACY]]))
add(sht3xd.Psht3xd.set_accuracy(constant))
sensor.setup_sensor(sht3xd.Psht3xd.Pget_temperature_sensor(), config[CONF_TEMPERATURE]) sensor.setup_sensor(sht3xd.Psht3xd.Pget_temperature_sensor(), sht3xd.Pmqtt_temperature,
sensor.setup_mqtt_sensor_component(sht3xd.Pmqtt_temperature, config[CONF_TEMPERATURE]) config[CONF_TEMPERATURE])
sensor.setup_sensor(sht3xd.Psht3xd.Pget_humidity_sensor(), sht3xd.Pmqtt_humidity,
sensor.setup_sensor(sht3xd.PPsht3xd.Pget_humidity_sensor(), config[CONF_HUMIDITY]) config[CONF_HUMIDITY])
sensor.setup_mqtt_sensor_component(sht3xd.Pmqtt_humidity, config[CONF_HUMIDITY])
BUILD_FLAGS = '-DUSE_SHT3XD' BUILD_FLAGS = '-DUSE_SHT3XD'

View file

@ -0,0 +1,25 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import sensor
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, process_lambda, variable, Application
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('template_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.SENSOR_SCHEMA.schema)
MakeTemplateSensor = Application.MakeTemplateSensor
def to_code(config):
template_ = process_lambda(config[CONF_LAMBDA], [])
rhs = App.make_template_sensor(config[CONF_NAME], template_,
config.get(CONF_UPDATE_INTERVAL))
make = variable(MakeTemplateSensor, config[CONF_MAKE_ID], rhs)
sensor.setup_sensor(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR'

View file

@ -2,20 +2,20 @@ 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_ADDRESS, CONF_GAIN, CONF_ID, CONF_INTEGRATION_TIME, CONF_NAME, \ from esphomeyaml.const import CONF_ADDRESS, CONF_GAIN, CONF_INTEGRATION_TIME, CONF_MAKE_ID, \
CONF_UPDATE_INTERVAL CONF_NAME, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, RawExpression, add, variable from esphomeyaml.helpers import App, Application, add, variable
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
INTEGRATION_TIMES = { INTEGRATION_TIMES = {
14: 'sensor::TSL2561_INTEGRATION_14MS', 14: sensor.sensor_ns.TSL2561_INTEGRATION_14MS,
101: 'sensor::TSL2561_INTEGRATION_101MS', 101: sensor.sensor_ns.TSL2561_INTEGRATION_101MS,
402: 'sensor::TSL2561_INTEGRATION_402MS', 402: sensor.sensor_ns.TSL2561_INTEGRATION_402MS,
} }
GAINS = { GAINS = {
'1X': 'sensor::TSL2561_GAIN_1X', '1X': sensor.sensor_ns.TSL2561_GAIN_1X,
'16X': 'sensor::TSL2561_GAIN_16X', '16X': sensor.sensor_ns.TSL2561_GAIN_16X,
} }
CONF_IS_CS_PACKAGE = 'is_cs_package' CONF_IS_CS_PACKAGE = 'is_cs_package'
@ -29,30 +29,29 @@ def validate_integration_time(value):
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('tsl2561_sensor'): cv.register_variable_id, cv.GenerateID('tsl2561_sensor', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_ADDRESS, default=0x39): cv.i2c_address, vol.Optional(CONF_ADDRESS, default=0x39): cv.i2c_address,
vol.Optional(CONF_INTEGRATION_TIME): validate_integration_time, vol.Optional(CONF_INTEGRATION_TIME): validate_integration_time,
vol.Optional(CONF_GAIN): vol.All(vol.Upper, vol.Any(*GAINS)), vol.Optional(CONF_GAIN): vol.All(vol.Upper, cv.one_of(*GAINS)),
vol.Optional(CONF_IS_CS_PACKAGE): cv.boolean, vol.Optional(CONF_IS_CS_PACKAGE): cv.boolean,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
MakeTSL2561Sensor = Application.MakeTSL2561Sensor
def to_code(config): def to_code(config):
rhs = App.make_tsl2561_sensor(config[CONF_NAME], config[CONF_ADDRESS], rhs = App.make_tsl2561_sensor(config[CONF_NAME], config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make_tsl = variable('Application::MakeTSL2561Sensor', config[CONF_ID], rhs) make_tsl = variable(MakeTSL2561Sensor, config[CONF_MAKE_ID], rhs)
tsl2561 = make_tsl.Ptsl2561 tsl2561 = make_tsl.Ptsl2561
if CONF_INTEGRATION_TIME in config: if CONF_INTEGRATION_TIME in config:
constant = INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]] add(tsl2561.set_integration_time(INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]]))
add(tsl2561.set_integration_time(RawExpression(constant)))
if CONF_GAIN in config: if CONF_GAIN in config:
constant = GAINS[config[CONF_GAIN]] add(tsl2561.set_gain(GAINS[config[CONF_GAIN]]))
add(tsl2561.set_gain(RawExpression(constant)))
if CONF_IS_CS_PACKAGE in config: if CONF_IS_CS_PACKAGE in config:
add(tsl2561.set_is_cs_package(config[CONF_IS_CS_PACKAGE])) add(tsl2561.set_is_cs_package(config[CONF_IS_CS_PACKAGE]))
sensor.setup_sensor(tsl2561, config) sensor.setup_sensor(tsl2561, make_tsl.Pmqtt, config)
sensor.setup_mqtt_sensor_component(make_tsl.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TSL2561' BUILD_FLAGS = '-DUSE_TSL2561'

View file

@ -3,19 +3,21 @@ 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_ECHO_PIN, CONF_ID, CONF_NAME, \ from esphomeyaml.const import CONF_ECHO_PIN, CONF_MAKE_ID, CONF_NAME, CONF_TIMEOUT_METER, \
CONF_TIMEOUT_METER, CONF_TIMEOUT_TIME, CONF_TRIGGER_PIN, CONF_UPDATE_INTERVAL CONF_TIMEOUT_TIME, CONF_TRIGGER_PIN, CONF_UPDATE_INTERVAL
from esphomeyaml.helpers import App, add, variable, gpio_output_pin_expression, \ from esphomeyaml.helpers import App, Application, add, gpio_input_pin_expression, \
gpio_input_pin_expression gpio_output_pin_expression, variable
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID('ultrasonic'): cv.register_variable_id, cv.GenerateID('ultrasonic', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_TRIGGER_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_TRIGGER_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
vol.Required(CONF_ECHO_PIN): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA, vol.Required(CONF_ECHO_PIN): pins.GPIO_INTERNAL_INPUT_PIN_SCHEMA,
vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float, vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float,
vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_time_period_microseconds, vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_time_period_microseconds,
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema) }).extend(sensor.SENSOR_SCHEMA.schema)
MakeUltrasonicSensor = Application.MakeUltrasonicSensor
def to_code(config): def to_code(config):
@ -23,14 +25,13 @@ def to_code(config):
echo = gpio_input_pin_expression(config[CONF_ECHO_PIN]) echo = gpio_input_pin_expression(config[CONF_ECHO_PIN])
rhs = App.make_ultrasonic_sensor(config[CONF_NAME], trigger, echo, rhs = App.make_ultrasonic_sensor(config[CONF_NAME], trigger, echo,
config.get(CONF_UPDATE_INTERVAL)) config.get(CONF_UPDATE_INTERVAL))
make = variable('Application::MakeUltrasonicSensor', config[CONF_ID], rhs) make = variable(MakeUltrasonicSensor, config[CONF_MAKE_ID], rhs)
ultrasonic = make.Pultrasonic ultrasonic = make.Pultrasonic
if CONF_TIMEOUT_TIME in config: if CONF_TIMEOUT_TIME in config:
add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME])) add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME]))
elif CONF_TIMEOUT_METER in config: elif CONF_TIMEOUT_METER in config:
add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER])) add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER]))
sensor.setup_sensor(ultrasonic, config) sensor.setup_sensor(ultrasonic, make.Pmqtt, config)
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_ULTRASONIC_SENSOR' BUILD_FLAGS = '-DUSE_ULTRASONIC_SENSOR'

View file

@ -1,39 +1,50 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ICON, CONF_INVERTED, CONF_MQTT_ID from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_INVERTED, CONF_MQTT_ID
from esphomeyaml.helpers import App, Pvariable, add, setup_mqtt_component from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, setup_mqtt_component
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
}) })
MQTT_SWITCH_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ SWITCH_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
cv.GenerateID('switch_'): cv.register_variable_id,
cv.GenerateID('mqtt_switch', CONF_MQTT_ID): cv.register_variable_id,
vol.Optional(CONF_ICON): cv.icon, vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_INVERTED): cv.boolean, vol.Optional(CONF_INVERTED): cv.boolean,
}) })
MQTT_SWITCH_ID_SCHEMA = MQTT_SWITCH_SCHEMA.extend({ switch_ns = esphomelib_ns.namespace('switch_')
cv.GenerateID('mqtt_switch', CONF_MQTT_ID): cv.register_variable_id, Switch = switch_ns.Switch
}) MQTTSwitchComponent = switch_ns.MQTTSwitchComponent
ToggleAction = switch_ns.ToggleAction
TurnOffAction = switch_ns.TurnOffAction
TurnOnAction = switch_ns.TurnOnAction
def setup_mqtt_switch(obj, config): def setup_switch_core_(switch_var, mqtt_var, config):
setup_mqtt_component(obj, config)
def setup_switch(obj, config):
if CONF_ICON in config: if CONF_ICON in config:
add(obj.set_icon(config[CONF_ICON])) add(switch_var.set_icon(config[CONF_ICON]))
if CONF_INVERTED in config: if CONF_INVERTED in config:
add(obj.set_inverted(config[CONF_INVERTED])) add(switch_var.set_inverted(config[CONF_INVERTED]))
setup_mqtt_component(mqtt_var, config)
def setup_switch(switch_obj, mqtt_obj, config):
switch_var = Pvariable(Switch, config[CONF_ID], switch_obj, has_side_effects=False)
mqtt_var = Pvariable(MQTTSwitchComponent, config[CONF_MQTT_ID], mqtt_obj,
has_side_effects=False)
setup_switch_core_(switch_var, mqtt_var, config)
def register_switch(var, config): def register_switch(var, config):
setup_switch(var, config) switch_var = Pvariable(Switch, config[CONF_ID], var, has_side_effects=True)
rhs = App.register_switch(var) rhs = App.register_switch(switch_var)
mqtt_switch = Pvariable('switch_::MQTTSwitchComponent', config[CONF_MQTT_ID], rhs) mqtt_var = Pvariable(MQTTSwitchComponent, config[CONF_MQTT_ID], rhs,
setup_mqtt_switch(mqtt_switch, config) has_side_effects=True)
setup_switch_core_(switch_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_SWITCH' BUILD_FLAGS = '-DUSE_SWITCH'

View file

@ -3,20 +3,21 @@ 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 switch from esphomeyaml.components import switch
from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_PIN from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN
from esphomeyaml.helpers import App, variable, gpio_output_pin_expression from esphomeyaml.helpers import App, Application, gpio_output_pin_expression, variable
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
cv.GenerateID('gpio_switch'): cv.register_variable_id, cv.GenerateID('gpio_switch', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA, vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
}).extend(switch.MQTT_SWITCH_SCHEMA.schema) }).extend(switch.SWITCH_SCHEMA.schema)
MakeGPIOSwitch = Application.MakeGPIOSwitch
def to_code(config): def to_code(config):
rhs = App.make_gpio_switch(config[CONF_NAME], gpio_output_pin_expression(config[CONF_PIN])) rhs = App.make_gpio_switch(config[CONF_NAME], gpio_output_pin_expression(config[CONF_PIN]))
gpio = variable('Application::MakeGPIOSwitch', config[CONF_ID], rhs) gpio = variable(MakeGPIOSwitch, config[CONF_MAKE_ID], rhs)
switch.setup_switch(gpio.Pswitch_, config) switch.setup_switch(gpio.Pswitch_, gpio.Pmqtt, config)
switch.setup_mqtt_switch(gpio.Pmqtt, config)
BUILD_FLAGS = '-DUSE_GPIO_SWITCH' BUILD_FLAGS = '-DUSE_GPIO_SWITCH'

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 switch from esphomeyaml.components import switch
from esphomeyaml.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS from esphomeyaml.components.ir_transmitter import IRTransmitterComponent
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \ from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \
CONF_ID, CONF_IR_TRANSMITTER_ID, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, \ CONF_ID, CONF_INVERTED, CONF_IR_TRANSMITTER_ID, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \
CONF_RAW, CONF_REPEAT, CONF_SONY, CONF_TIMES, CONF_WAIT_TIME, CONF_INVERTED CONF_PANASONIC, CONF_RAW, CONF_REPEAT, CONF_SONY, CONF_TIMES, CONF_WAIT_TIME
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import ArrayInitializer, HexIntLiteral, MockObj, Pvariable, get_variable from esphomeyaml.helpers import App, ArrayInitializer, HexIntLiteral, Pvariable, \
get_variable
DEPENDENCIES = ['ir_transmitter'] DEPENDENCIES = ['ir_transmitter']
@ -46,10 +47,12 @@ PLATFORM_SCHEMA = vol.All(switch.PLATFORM_SCHEMA.extend({
})), })),
vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id, vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id,
vol.Optional(CONF_INVERTED): cv.invalid("IR Transmitters do not support inverted mode!"), vol.Optional(CONF_INVERTED): cv.invalid("IR Transmitters do not support inverted mode!"),
}).extend(switch.MQTT_SWITCH_ID_SCHEMA.schema), cv.has_at_least_one_key(*IR_KEYS)) }).extend(switch.SWITCH_SCHEMA.schema), cv.has_at_least_one_key(*IR_KEYS))
# pylint: disable=invalid-name # pylint: disable=invalid-name
SendData = MockObj('switch_::ir::SendData', '::') ir_ns = switch.switch_ns.namespace('ir')
SendData = ir_ns.namespace('SendData')
DataTransmitter = IRTransmitterComponent.DataTransmitter
def safe_hex(value): def safe_hex(value):
@ -87,17 +90,15 @@ def exp_send_data(config):
else: else:
times = config[CONF_REPEAT][CONF_TIMES] times = config[CONF_REPEAT][CONF_TIMES]
wait_us = config[CONF_REPEAT][CONF_WAIT_TIME] wait_us = config[CONF_REPEAT][CONF_WAIT_TIME]
base = MockObj(unicode(base), u'.')
base = base.repeat(times, wait_us) base = base.repeat(times, wait_us)
return base return base
def to_code(config): def to_code(config):
ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IR_TRANSMITTER_COMPONENT_CLASS) ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IRTransmitterComponent)
send_data = exp_send_data(config) send_data = exp_send_data(config)
rhs = ir.create_transmitter(config[CONF_NAME], send_data) rhs = App.register_component(ir.create_transmitter(config[CONF_NAME], send_data))
switch_ = Pvariable(IR_TRANSMITTER_COMPONENT_CLASS + '::DataTransmitter', config[CONF_ID], switch_ = Pvariable(DataTransmitter, config[CONF_ID], rhs)
rhs)
switch.register_switch(switch_, config) switch.register_switch(switch_, config)

View file

@ -2,21 +2,22 @@ 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.const import CONF_ID, CONF_NAME, CONF_OUTPUT from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT
from esphomeyaml.helpers import App, get_variable, variable from esphomeyaml.helpers import App, Application, get_variable, variable
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
cv.GenerateID('output_switch'): cv.register_variable_id, cv.GenerateID('output_switch', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_OUTPUT): cv.variable_id, vol.Required(CONF_OUTPUT): cv.variable_id,
}).extend(switch.MQTT_SWITCH_SCHEMA.schema) }).extend(switch.SWITCH_SCHEMA.schema)
MakeSimpleSwitch = Application.MakeSimpleSwitch
def to_code(config): def to_code(config):
output = get_variable(config[CONF_OUTPUT]) output = get_variable(config[CONF_OUTPUT])
rhs = App.make_simple_switch(config[CONF_NAME], output) rhs = App.make_simple_switch(config[CONF_NAME], output)
gpio = variable('Application::MakeSimpleSwitch', config[CONF_ID], rhs) gpio = variable(MakeSimpleSwitch, config[CONF_MAKE_ID], rhs)
switch.setup_switch(gpio.Pswitch_, config) switch.setup_switch(gpio.Pswitch_, gpio.Pmqtt, config)
switch.setup_mqtt_switch(gpio.Pmqtt, config)
BUILD_FLAGS = '-DUSE_SIMPLE_SWITCH' BUILD_FLAGS = '-DUSE_SIMPLE_SWITCH'

View file

@ -2,20 +2,21 @@ 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.const import CONF_ID, CONF_NAME, CONF_INVERTED from esphomeyaml.const import CONF_INVERTED, CONF_MAKE_ID, CONF_NAME
from esphomeyaml.helpers import App, variable from esphomeyaml.helpers import App, Application, variable
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
cv.GenerateID('restart_switch'): cv.register_variable_id, cv.GenerateID('restart_switch', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_INVERTED): cv.invalid("Restart switches do not support inverted mode!"), vol.Optional(CONF_INVERTED): cv.invalid("Restart switches do not support inverted mode!"),
}).extend(switch.MQTT_SWITCH_SCHEMA.schema) }).extend(switch.SWITCH_SCHEMA.schema)
MakeRestartSwitch = Application.MakeRestartSwitch
def to_code(config): def to_code(config):
rhs = App.make_restart_switch(config[CONF_NAME]) rhs = App.make_restart_switch(config[CONF_NAME])
restart = variable('Application::MakeRestartSwitch', config[CONF_ID], rhs) restart = variable(MakeRestartSwitch, config[CONF_MAKE_ID], rhs)
switch.setup_switch(restart.Prestart, config) switch.setup_switch(restart.Prestart, restart.Pmqtt, config)
switch.setup_mqtt_switch(restart.Pmqtt, config)
BUILD_FLAGS = '-DUSE_RESTART_SWITCH' BUILD_FLAGS = '-DUSE_RESTART_SWITCH'

View file

@ -2,21 +2,21 @@ 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.const import CONF_ID, CONF_NAME, CONF_INVERTED from esphomeyaml.const import CONF_INVERTED, CONF_MAKE_ID, CONF_NAME
from esphomeyaml.helpers import App, variable from esphomeyaml.helpers import App, Application, variable
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
cv.GenerateID('shutdown_switch'): cv.register_variable_id, cv.GenerateID('shutdown_switch', CONF_MAKE_ID): cv.register_variable_id,
vol.Optional(CONF_INVERTED): cv.invalid("Shutdown switches do not support inverted mode!"), vol.Optional(CONF_INVERTED): cv.invalid("Shutdown switches do not support inverted mode!"),
}).extend(switch.MQTT_SWITCH_SCHEMA.schema) }).extend(switch.SWITCH_SCHEMA.schema)
MakeShutdownSwitch = Application.MakeShutdownSwitch
def to_code(config): def to_code(config):
rhs = App.make_shutdown_switch(config[CONF_NAME]) rhs = App.make_shutdown_switch(config[CONF_NAME])
shutdown = variable('Application::MakeShutdownSwitch', config[CONF_ID], shutdown = variable(MakeShutdownSwitch, config[CONF_MAKE_ID], rhs)
rhs) switch.setup_switch(shutdown.Pshutdown, shutdown.Pmqtt, config)
switch.setup_switch(shutdown.Pshutdown, config)
switch.setup_mqtt_switch(shutdown.Pmqtt, config)
BUILD_FLAGS = '-DUSE_SHUTDOWN_SWITCH' BUILD_FLAGS = '-DUSE_SHUTDOWN_SWITCH'

View file

@ -0,0 +1,35 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import automation
from esphomeyaml.components import switch
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, CONF_TURN_OFF_ACTION, \
CONF_TURN_ON_ACTION
from esphomeyaml.helpers import App, Application, process_lambda, variable, NoArg, add
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
cv.GenerateID('template_switch', CONF_MAKE_ID): cv.register_variable_id,
vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_TURN_OFF_ACTION): automation.ACTIONS_SCHEMA,
vol.Optional(CONF_TURN_ON_ACTION): automation.ACTIONS_SCHEMA,
}).extend(switch.SWITCH_SCHEMA.schema)
MakeTemplateSwitch = Application.MakeTemplateSwitch
def to_code(config):
template_ = process_lambda(config[CONF_LAMBDA], [])
rhs = App.make_template_switch(config[CONF_NAME], template_)
make = variable(MakeTemplateSwitch, config[CONF_MAKE_ID], rhs)
if CONF_TURN_OFF_ACTION in config:
actions = automation.build_actions(config[CONF_TURN_OFF_ACTION], NoArg)
add(make.Ptemplate_.add_turn_off_actions(actions))
if CONF_TURN_ON_ACTION in config:
actions = automation.build_actions(config[CONF_TURN_ON_ACTION], NoArg)
add(make.Ptemplate_.add_turn_on_actions(actions))
switch.setup_switch(make.Ptemplate_, make.Pmqtt, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_SWITCH'

View file

@ -5,7 +5,7 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import core from esphomeyaml import core
from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID, ESP_PLATFORM_ESP32 from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID, ESP_PLATFORM_ESP32
from esphomeyaml.helpers import App, add, Pvariable from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -16,10 +16,12 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_JS_URL): vol.Url, vol.Optional(CONF_JS_URL): vol.Url,
}) })
WebServer = esphomelib_ns.WebServer
def to_code(config): def to_code(config):
rhs = App.init_web_server(config.get(CONF_PORT)) rhs = App.init_web_server(config.get(CONF_PORT))
web_server = Pvariable('WebServer', config[CONF_ID], rhs) web_server = Pvariable(WebServer, config[CONF_ID], rhs)
if CONF_CSS_URL in config: if CONF_CSS_URL in config:
add(web_server.set_css_url(config[CONF_CSS_URL])) add(web_server.set_css_url(config[CONF_CSS_URL]))
if CONF_JS_URL in config: if CONF_JS_URL in config:

View file

@ -5,7 +5,7 @@ from esphomeyaml import core
from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_GATEWAY, \ from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_GATEWAY, \
CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, \ CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, \
ESP_PLATFORM_ESP8266 ESP_PLATFORM_ESP8266
from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, esphomelib_ns, global_ns
def validate_password(value): def validate_password(value):
@ -45,7 +45,9 @@ CONFIG_SCHEMA = vol.Schema({
}) })
# pylint: disable=invalid-name # pylint: disable=invalid-name
IPAddress = MockObj('IPAddress') IPAddress = global_ns.IPAddress
ManualIP = esphomelib_ns.ManualIP
WiFiComponent = esphomelib_ns.WiFiComponent
def safe_ip(ip): def safe_ip(ip):
@ -56,7 +58,7 @@ def safe_ip(ip):
def manual_ip(config): def manual_ip(config):
return StructInitializer( return StructInitializer(
'ManualIP', ManualIP,
('static_ip', safe_ip(config[CONF_STATIC_IP])), ('static_ip', safe_ip(config[CONF_STATIC_IP])),
('gateway', safe_ip(config[CONF_GATEWAY])), ('gateway', safe_ip(config[CONF_GATEWAY])),
('subnet', safe_ip(config[CONF_SUBNET])), ('subnet', safe_ip(config[CONF_SUBNET])),
@ -72,7 +74,7 @@ def to_code(config):
rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD)) rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD))
else: else:
rhs = App.init_wifi() rhs = App.init_wifi()
wifi = Pvariable('WiFiComponent', config[CONF_ID], rhs) wifi = Pvariable(WiFiComponent, config[CONF_ID], rhs)
if sta and CONF_MANUAL_IP in config: if sta and CONF_MANUAL_IP in config:
add(wifi.set_sta_manual_ip(manual_ip(config[CONF_MANUAL_IP]))) add(wifi.set_sta_manual_ip(manual_ip(config[CONF_MANUAL_IP])))

View file

@ -29,7 +29,7 @@ CORE_SCHEMA = vol.Schema({
vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string, vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string,
vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean, vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean,
vol.Optional(CONF_USE_BUILD_FLAGS, default=True): cv.boolean, vol.Optional(CONF_USE_BUILD_FLAGS, default=True): cv.boolean,
vol.Optional(CONF_BOARD_FLASH_MODE): vol.All(vol.Lower, vol.Any(*BUILD_FLASH_MODES)), vol.Optional(CONF_BOARD_FLASH_MODE): vol.All(vol.Lower, cv.one_of(*BUILD_FLASH_MODES)),
}) })
REQUIRED_COMPONENTS = [ REQUIRED_COMPONENTS = [
@ -171,6 +171,12 @@ def validate_config(config):
if not success: if not success:
continue continue
esp_platforms = getattr(platform, 'ESP_PLATFORMS', ESP_PLATFORMS)
if core.ESP_PLATFORM not in esp_platforms:
result.add_error(
u"Platform {}.{} doesn't support {}.".format(domain, p_name, core.ESP_PLATFORM))
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)

View file

@ -12,8 +12,8 @@ from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOV
CONF_NAME, CONF_PAYLOAD_AVAILABLE, \ CONF_NAME, CONF_PAYLOAD_AVAILABLE, \
CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \ CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266 ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
from esphomeyaml.core import HexInt, IPAddress, TimePeriod, TimePeriodMilliseconds, \ from esphomeyaml.core import HexInt, IPAddress, TimePeriod, TimePeriodMicroseconds, \
TimePeriodMicroseconds, TimePeriodSeconds TimePeriodMilliseconds, TimePeriodSeconds, Lambda
from esphomeyaml.helpers import ensure_unique_string from esphomeyaml.helpers import ensure_unique_string
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -134,7 +134,7 @@ def int_(value):
hex_int = vol.Coerce(hex_int_) hex_int = vol.Coerce(hex_int_)
match_cpp_var_ = vol.Match(r'^[a-zA-Z_][a-zA-Z0-9_]+$', msg=u"Must be a valid C++ variable name") match_cpp_var_ = vol.Match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', msg=u"Must be a valid C++ variable name")
def variable_id(value): def variable_id(value):
@ -144,6 +144,14 @@ def variable_id(value):
return value return value
def templatable(other_validators):
def validator(value):
if isinstance(value, Lambda):
return value
return other_validators(value)
return validator
def only_on(platforms): def only_on(platforms):
if not isinstance(platforms, list): if not isinstance(platforms, list):
platforms = [platforms] platforms = [platforms]
@ -170,10 +178,24 @@ def has_at_least_one_key(*keys):
if not isinstance(obj, dict): if not isinstance(obj, dict):
raise vol.Invalid('expected dictionary') raise vol.Invalid('expected dictionary')
for k in obj.keys(): if not any(k in keys for k in obj):
if k in keys: raise vol.Invalid('Must contain at least one of {}.'.format(', '.join(keys)))
return obj
return validate
def has_at_exactly_one_key(*keys):
def validate(obj):
if not isinstance(obj, dict):
raise vol.Invalid('expected dictionary')
number = sum(k in keys for k in obj)
if number > 1:
raise vol.Invalid("Cannot specify more than one of {}.".format(', '.join(keys)))
if number < 1:
raise vol.Invalid('Must contain exactly one of {}.'.format(', '.join(keys)))
return obj return obj
raise vol.Invalid('must contain one of {}.'.format(', '.join(keys)))
return validate return validate
@ -410,6 +432,14 @@ def mqtt_payload(value):
return string(value) return string(value)
def mqtt_qos(value):
try:
value = int(value)
except (TypeError, ValueError):
raise vol.Invalid(u"MQTT Quality of Service must be integer, got {}".format(value))
return one_of(0, 1, 2)(value)
uint8_t = vol.All(int_, vol.Range(min=0, max=255)) uint8_t = vol.All(int_, vol.Range(min=0, max=255))
uint16_t = vol.All(int_, vol.Range(min=0, max=65535)) uint16_t = vol.All(int_, vol.Range(min=0, max=65535))
uint32_t = vol.All(int_, vol.Range(min=0, max=4294967295)) uint32_t = vol.All(int_, vol.Range(min=0, max=4294967295))
@ -429,6 +459,22 @@ def valid(value):
return value return value
def one_of(*values):
options = u', '.join(u"'{}'".format(x) for x in values)
def validator(value):
if value not in values:
raise vol.Invalid(u"Unknown value '{}', must be one of {}".format(value, options))
return value
return validator
def lambda_(value):
if isinstance(value, Lambda):
return value
return Lambda(string_strict(value))
REGISTERED_IDS = set() REGISTERED_IDS = set()

View file

@ -34,6 +34,13 @@ CONF_USERNAME = 'username'
CONF_POWER_SUPPLY = 'power_supply' CONF_POWER_SUPPLY = 'power_supply'
CONF_ID = 'id' CONF_ID = 'id'
CONF_MQTT_ID = 'mqtt_id' CONF_MQTT_ID = 'mqtt_id'
CONF_SENSOR_ID = 'sensor_id'
CONF_TRIGGER_ID = 'trigger_id'
CONF_ACTION_ID = 'action_id'
CONF_CONDITION_ID = 'condition_id'
CONF_MAKE_ID = 'make_id'
CONF_AUTOMATION_ID = 'automation_id'
CONF_DELAY = 'delay'
CONF_PIN = 'pin' CONF_PIN = 'pin'
CONF_NUMBER = 'number' CONF_NUMBER = 'number'
CONF_INVERTED = 'inverted' CONF_INVERTED = 'inverted'
@ -70,6 +77,15 @@ CONF_TOPIC = 'topic'
CONF_PAYLOAD_AVAILABLE = 'payload_available' CONF_PAYLOAD_AVAILABLE = 'payload_available'
CONF_PAYLOAD_NOT_AVAILABLE = 'payload_not_available' CONF_PAYLOAD_NOT_AVAILABLE = 'payload_not_available'
CONF_DEFAULT_TRANSITION_LENGTH = 'default_transition_length' CONF_DEFAULT_TRANSITION_LENGTH = 'default_transition_length'
CONF_TRANSITION_LENGTH = 'transition_length'
CONF_FLASH_LENGTH = 'flash_length'
CONF_BRIGHTNESS = 'brightness'
CONF_EFFECT = 'effect'
CONF_MIN = 'min'
CONF_MAX = 'max'
CONF_ON = 'on'
CONF_IF = 'if'
CONF_THEN = 'then'
CONF_BINARY = 'binary' CONF_BINARY = 'binary'
CONF_WHITE = 'white' CONF_WHITE = 'white'
CONF_RGBW = 'rgbw' CONF_RGBW = 'rgbw'
@ -112,6 +128,8 @@ CONF_LAMBDA = 'lambda'
CONF_THROTTLE = 'throttle' CONF_THROTTLE = 'throttle'
CONF_DELTA = 'delta' CONF_DELTA = 'delta'
CONF_OR = 'or' CONF_OR = 'or'
CONF_AND = 'and'
CONF_RANGE = 'range'
CONF_UNIQUE = 'unique' CONF_UNIQUE = 'unique'
CONF_HEARTBEAT = 'heartbeat' CONF_HEARTBEAT = 'heartbeat'
CONF_DEBOUNCE = 'debounce' CONF_DEBOUNCE = 'debounce'
@ -192,6 +210,24 @@ CONF_CLOCK_PIN = 'clock_pin'
CONF_RGB_ORDER = 'rgb_order' CONF_RGB_ORDER = 'rgb_order'
CONF_ACCURACY = 'accuracy' CONF_ACCURACY = 'accuracy'
CONF_BOARD_FLASH_MODE = 'board_flash_mode' CONF_BOARD_FLASH_MODE = 'board_flash_mode'
CONF_ON_PRESS = 'on_press'
CONF_ON_RELEASE = 'on_release'
CONF_ON_CLICK = 'on_click'
CONF_ON_DOUBLE_CLICK = 'on_double_click'
CONF_MIN_LENGTH = 'min_length'
CONF_MAX_LENGTH = 'max_length'
CONF_ON_VALUE = 'on_value'
CONF_ON_RAW_VALUE = 'on_raw_value'
CONF_ON_VALUE_RANGE = 'on_value_range'
CONF_ON_MESSAGE = 'on_message'
CONF_PIN_CS = 'pin_cs'
CONF_PIN_CLOCK = 'pin_clock'
CONF_PIN_MISO = 'pin_miso'
CONF_TURN_ON_ACTION = 'turn_on_action'
CONF_TURN_OFF_ACTION = 'turn_off_action'
CONF_OPEN_ACTION = 'open_action'
CONF_CLOSE_ACTION = 'close_action'
CONF_STOP_ACTION = 'stop_action'
ESP32_BOARDS = [ ESP32_BOARDS = [
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', 'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',

View file

@ -171,6 +171,14 @@ class TimePeriodSeconds(TimePeriod):
pass pass
class Lambda(object):
def __init__(self, value):
self.value = value
def __str__(self):
return u'Lambda<{}>'.format(self.value)
CONFIG_PATH = None CONFIG_PATH = None
SIMPLIFY = True SIMPLIFY = True
ESP_PLATFORM = '' ESP_PLATFORM = ''

View file

@ -10,7 +10,7 @@ from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOV
CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PCF8574, \ CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PCF8574, \
CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC
from esphomeyaml.core import ESPHomeYAMLError, HexInt, TimePeriodMicroseconds, \ from esphomeyaml.core import ESPHomeYAMLError, HexInt, TimePeriodMicroseconds, \
TimePeriodMilliseconds, TimePeriodSeconds TimePeriodMilliseconds, TimePeriodSeconds, Lambda
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -58,6 +58,9 @@ class Expression(object):
continue continue
require.require() require.require()
def has_side_effects(self):
return self.required
class RawExpression(Expression): class RawExpression(Expression):
def __init__(self, text): def __init__(self, text):
@ -65,7 +68,7 @@ class RawExpression(Expression):
self.text = text self.text = text
def __str__(self): def __str__(self):
return self.text return str(self.text)
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin
@ -85,6 +88,9 @@ class AssignmentExpression(Expression):
type_ = u'auto' type_ = u'auto'
return u"{} {}{} = {}".format(type_, self.modifier, self.name, self.rhs) return u"{} {}{} = {}".format(type_, self.modifier, self.name, self.rhs)
def has_side_effects(self):
return self.rhs.has_side_effects()
class ExpressionList(Expression): class ExpressionList(Expression):
def __init__(self, *args): def __init__(self, *args):
@ -100,7 +106,7 @@ class ExpressionList(Expression):
self.args.append(exp) self.args.append(exp)
def __str__(self): def __str__(self):
text = u", ".join(unicode(x) for x in self.args) text = u", ".join(str(x) for x in self.args)
return indent_all_but_first_and_last(text) return indent_all_but_first_and_last(text)
@ -137,6 +143,8 @@ class StructInitializer(Expression):
def __init__(self, base, *args): def __init__(self, base, *args):
super(StructInitializer, self).__init__() super(StructInitializer, self).__init__()
self.base = base self.base = base
if isinstance(base, Expression):
self.requires.append(base)
if not isinstance(args, OrderedDict): if not isinstance(args, OrderedDict):
args = OrderedDict(args) args = OrderedDict(args)
self.args = OrderedDict() self.args = OrderedDict()
@ -180,6 +188,57 @@ class ArrayInitializer(Expression):
return cpp return cpp
# pylint: disable=invalid-name
class ParameterExpression(Expression):
def __init__(self, type, id):
super(ParameterExpression, self).__init__()
self.type = type
self.id = id
def __str__(self):
return u"{} {}".format(self.type, self.id)
class ParameterListExpression(Expression):
def __init__(self, *parameters):
super(ParameterListExpression, self).__init__()
self.parameters = []
for parameter in parameters:
if not isinstance(parameter, ParameterExpression):
parameter = ParameterExpression(*parameter)
self.parameters.append(parameter)
self.requires.append(parameter)
def __str__(self):
return u", ".join(unicode(x) for x in self.parameters)
class LambdaExpression(Expression):
def __init__(self, parts, parameters, capture='=', return_type=None):
super(LambdaExpression, self).__init__()
self.parts = parts
if not isinstance(parameters, ParameterListExpression):
parameters = ParameterListExpression(*parameters)
self.parameters = parameters
self.requires.append(self.parameters)
self.capture = capture
self.return_type = return_type
if return_type is not None:
self.requires.append(return_type)
for i in range(1, len(parts), 2):
self.requires.append(parts[i])
def __str__(self):
cpp = u'[{}]({})'.format(self.capture, self.parameters)
if self.return_type is not None:
cpp += u' -> {}'.format(self.return_type)
cpp += u' {\n'
for part in self.parts:
cpp += unicode(part)
cpp += u'\n}'
return indent_all_but_first_and_last(cpp)
class Literal(Expression): class Literal(Expression):
def __str__(self): def __str__(self):
raise NotImplementedError raise NotImplementedError
@ -235,9 +294,9 @@ class HexIntLiteral(Literal):
class FloatLiteral(Literal): class FloatLiteral(Literal):
def __init__(self, float_): def __init__(self, value):
super(FloatLiteral, self).__init__() super(FloatLiteral, self).__init__()
self.float_ = float_ self.float_ = value
def __str__(self): def __str__(self):
return u"{:f}f".format(self.float_) return u"{:f}f".format(self.float_)
@ -297,23 +356,30 @@ def statement(expression):
return ExpressionStatement(expression) return ExpressionStatement(expression)
def register_variable(type, id, obj):
_VARIABLES[id] = obj, type
# pylint: disable=redefined-builtin, invalid-name # pylint: disable=redefined-builtin, invalid-name
def variable(type, id, rhs): def variable(type, id, rhs):
rhs = safe_exp(rhs) rhs = safe_exp(rhs)
obj = MockObj(id, u'.') obj = MockObj(id, u'.')
assignment = AssignmentExpression(type, '', id, rhs, obj) assignment = AssignmentExpression(type, '', id, rhs, obj)
add(assignment) add(assignment)
_VARIABLES[id] = obj, type register_variable(type, id, obj)
obj.requires.append(assignment) obj.requires.append(assignment)
return obj return obj
def Pvariable(type, id, rhs): def Pvariable(type, id, rhs, has_side_effects=True):
rhs = safe_exp(rhs) rhs = safe_exp(rhs)
obj = MockObj(id, u'->') if not has_side_effects and hasattr(rhs, '_has_side_effects'):
# pylint: disable=attribute-defined-outside-init, protected-access
rhs._has_side_effects = False
obj = MockObj(id, u'->', has_side_effects=has_side_effects)
assignment = AssignmentExpression(type, '*', id, rhs, obj) assignment = AssignmentExpression(type, '*', id, rhs, obj)
add(assignment) add(assignment)
_VARIABLES[id] = obj, type register_variable(type, id, obj)
obj.requires.append(assignment) obj.requires.append(assignment)
return obj return obj
@ -324,32 +390,41 @@ _EXPRESSIONS = []
def get_variable(id, type=None): def get_variable(id, type=None):
result = None def get_result():
while _QUEUE:
if id is not None: if id is not None:
if id in _VARIABLES: if id in _VARIABLES:
result = _VARIABLES[id][0] return _VARIABLES[id][0]
break
elif type is not None: elif type is not None:
result = next((x[0] for x in _VARIABLES.itervalues() if x[1] == type), None) return next((x[0] for x in _VARIABLES.itervalues() if x[1] == type), None)
return None
while _QUEUE:
result = get_result()
if result is not None: if result is not None:
break return result
func, config = _QUEUE.popleft() func, config = _QUEUE.popleft()
func(config) func(config)
if id is None and type is None: if id is None and type is None:
return None return None
if result is None: result = get_result()
if id is not None:
if id in _VARIABLES:
result = _VARIABLES[id][0]
elif type is not None:
result = next((x[0] for x in _VARIABLES.itervalues() if x[1] == type), None)
if result is None: if result is None:
raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type {}".format(id, type)) raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type {}".format(id, type))
return result return result
def process_lambda(value, parameters, capture='=', return_type=None):
parts = re.split(r'id\(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\)\.', value.value)
for i in range(1, len(parts), 2):
parts[i] = get_variable(parts[i])._
return LambdaExpression(parts, parameters, capture, return_type)
def templatable(value, input_type, output_type):
if isinstance(value, Lambda):
return process_lambda(value, [(input_type, 'x')], return_type=output_type)
return value
def add_task(func, config): def add_task(func, config):
_QUEUE.append((func, config)) _QUEUE.append((func, config))
@ -362,18 +437,28 @@ def add(expression, require=True):
class MockObj(Expression): class MockObj(Expression):
def __init__(self, base, op=u'.'): def __init__(self, base, op=u'.', has_side_effects=True):
self.base = base self.base = base
self.op = op self.op = op
self._has_side_effects = has_side_effects
super(MockObj, self).__init__() super(MockObj, self).__init__()
def __getattr__(self, attr): def __getattr__(self, attr):
if attr == u'_':
obj = MockObj(u'{}{}'.format(self.base, self.op))
obj.requires.append(self)
return obj
if attr == u'new':
obj = MockObj(u'new {}'.format(self.base), u'->')
obj.requires.append(self)
return obj
next_op = u'.' next_op = u'.'
if attr.startswith(u'P'): if attr.startswith(u'P') and self.op != '::':
attr = attr[1:] attr = attr[1:]
next_op = u'->' next_op = u'->'
op = self.op if attr.startswith(u'_'):
obj = MockObj(u'{}{}{}'.format(self.base, op, attr), next_op) attr = attr[1:]
obj = MockObj(u'{}{}{}'.format(self.base, self.op, attr), next_op)
obj.requires.append(self) obj.requires.append(self)
return obj return obj
@ -394,12 +479,41 @@ class MockObj(Expression):
continue continue
require.require() require.require()
def template(self, args):
if not isinstance(args, TemplateArguments):
args = TemplateArguments(args)
obj = MockObj(u'{}{}'.format(self.base, args))
obj.requires.append(self)
obj.requires.append(args)
return obj
App = MockObj(u'App') def namespace(self, name):
obj = MockObj(u'{}{}{}'.format(self.base, self.op, name), u'::')
obj.requires.append(self)
return obj
GPIOPin = MockObj(u'GPIOPin') def has_side_effects(self):
GPIOOutputPin = MockObj(u'GPIOOutputPin') return self._has_side_effects
GPIOInputPin = MockObj(u'GPIOInputPin')
global_ns = MockObj('', '')
float_ = global_ns.namespace('float')
bool_ = global_ns.namespace('bool')
std_ns = global_ns.namespace('std')
std_string = std_ns.string
uint8 = global_ns.namespace('uint8_t')
uint16 = global_ns.namespace('uint16_t')
uint32 = global_ns.namespace('uint32_t')
NAN = global_ns.namespace('NAN')
esphomelib_ns = global_ns # using namespace esphomelib;
NoArg = esphomelib_ns.NoArg
App = esphomelib_ns.App
Application = esphomelib_ns.namespace('Application')
optional = esphomelib_ns.optional
GPIOPin = esphomelib_ns.GPIOPin
GPIOOutputPin = esphomelib_ns.GPIOOutputPin
GPIOInputPin = esphomelib_ns.GPIOInputPin
def get_gpio_pin_number(conf): def get_gpio_pin_number(conf):
@ -453,15 +567,6 @@ def setup_mqtt_component(obj, config):
availability[CONF_PAYLOAD_NOT_AVAILABLE])) availability[CONF_PAYLOAD_NOT_AVAILABLE]))
def exp_empty_optional(type):
return RawExpression(u'Optional<{}>()'.format(type))
def exp_optional(type, value):
if value is None:
return exp_empty_optional(type)
return value
# shlex's quote for Python 2.7 # shlex's quote for Python 2.7
_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search _find_unsafe = re.compile(r'[^\w@%+=:,./-]').search

View file

@ -64,7 +64,8 @@ ESP32_BOARD_TO_PINS = {
def _translate_pin(value): def _translate_pin(value):
if isinstance(value, dict) or value is None: if isinstance(value, dict) or value is None:
raise vol.Invalid(u"This option doesn't allow more complicated options like inverted.") raise vol.Invalid(u"This variable only supports pin numbers, not full pin schemas "
u"(with inverted and mode).")
if isinstance(value, int): if isinstance(value, int):
return value return value
try: try:
@ -171,9 +172,9 @@ PIN_MODES_ESP32 = [
def pin_mode(value): def pin_mode(value):
value = vol.All(vol.Coerce(str), vol.Upper)(value) value = vol.All(vol.Coerce(str), vol.Upper)(value)
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32: if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
return vol.Any(*PIN_MODES_ESP32)(value) return cv.one_of(*PIN_MODES_ESP32)(value)
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
return vol.Any(*PIN_MODES_ESP8266)(value) return cv.one_of(*PIN_MODES_ESP8266)(value)
raise vol.Invalid(u"Invalid ESP platform.") raise vol.Invalid(u"Invalid ESP platform.")

View file

@ -8,8 +8,7 @@ from collections import OrderedDict
import yaml import yaml
from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress, MACAddress, TimePeriod, \ from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress, Lambda, MACAddress, TimePeriod
TimePeriodMicroseconds, TimePeriodMilliseconds, TimePeriodSeconds
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -195,6 +194,10 @@ def _secret_yaml(loader, node):
return secrets[node.value] return secrets[node.value]
def _lambda(loader, node):
return Lambda(unicode(node.value))
yaml.SafeLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, _ordered_dict) yaml.SafeLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, _ordered_dict)
yaml.SafeLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_SEQUENCE_TAG, _construct_seq) yaml.SafeLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_SEQUENCE_TAG, _construct_seq)
yaml.SafeLoader.add_constructor('!env_var', _env_var_yaml) yaml.SafeLoader.add_constructor('!env_var', _env_var_yaml)
@ -206,6 +209,7 @@ yaml.SafeLoader.add_constructor('!include_dir_merge_list',
yaml.SafeLoader.add_constructor('!include_dir_named', _include_dir_named_yaml) yaml.SafeLoader.add_constructor('!include_dir_named', _include_dir_named_yaml)
yaml.SafeLoader.add_constructor('!include_dir_merge_named', yaml.SafeLoader.add_constructor('!include_dir_merge_named',
_include_dir_merge_named_yaml) _include_dir_merge_named_yaml)
yaml.SafeLoader.add_constructor('!lambda', _lambda)
# From: https://gist.github.com/miracle2k/3184458 # From: https://gist.github.com/miracle2k/3184458
@ -270,6 +274,11 @@ def represent_time_period(dumper, data):
return represent_odict(dumper, 'tag:yaml.org,2002:map', dictionary) return represent_odict(dumper, 'tag:yaml.org,2002:map', dictionary)
def represent_lambda(_, data):
node = yaml.ScalarNode(tag='!lambda', value=data.value, style='>')
return node
yaml.SafeDumper.add_representer( yaml.SafeDumper.add_representer(
OrderedDict, OrderedDict,
lambda dumper, value: lambda dumper, value:
@ -286,7 +295,5 @@ yaml.SafeDumper.add_representer(unicode, unicode_representer)
yaml.SafeDumper.add_representer(HexInt, hex_int_representer) yaml.SafeDumper.add_representer(HexInt, hex_int_representer)
yaml.SafeDumper.add_representer(IPAddress, stringify_representer) yaml.SafeDumper.add_representer(IPAddress, stringify_representer)
yaml.SafeDumper.add_representer(MACAddress, stringify_representer) yaml.SafeDumper.add_representer(MACAddress, stringify_representer)
yaml.SafeDumper.add_representer(TimePeriod, represent_time_period) yaml.SafeDumper.add_multi_representer(TimePeriod, represent_time_period)
yaml.SafeDumper.add_representer(TimePeriodMicroseconds, represent_time_period) yaml.SafeDumper.add_multi_representer(Lambda, represent_lambda)
yaml.SafeDumper.add_representer(TimePeriodMilliseconds, represent_time_period)
yaml.SafeDumper.add_representer(TimePeriodSeconds, represent_time_period)

View file

@ -14,6 +14,8 @@ disable=
too-many-arguments, too-many-arguments,
too-many-return-statements, too-many-return-statements,
duplicate-code, duplicate-code,
invalid-name,
cyclic-import,
additional-builtins= additional-builtins=