mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 12:15:33 +01:00
parent
ac5ab33975
commit
3540b3fbb0
@ -6,19 +6,16 @@ import os
|
||||
import random
|
||||
import sys
|
||||
|
||||
from esphomeyaml import helpers, mqtt, writer, yaml_util, wizard
|
||||
from esphomeyaml.config import add_component_task, read_config
|
||||
from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_MANUAL_IP, CONF_NAME, \
|
||||
CONF_STATIC_IP, \
|
||||
CONF_WIFI, CONF_LOGGER, CONF_BAUD_RATE
|
||||
from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, \
|
||||
get_variable, indent, quote, statement, color
|
||||
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.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_HOSTNAME, CONF_LOGGER, \
|
||||
CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI
|
||||
from esphomeyaml.helpers import AssignmentExpression, RawStatement, _EXPRESSIONS, add, add_task, \
|
||||
color, get_variable, indent, quote, statement, Expression
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'i2c']
|
||||
|
||||
CONFIG_PATH = None
|
||||
PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'web_server', 'i2c']
|
||||
|
||||
|
||||
def get_name(config):
|
||||
@ -26,7 +23,7 @@ def get_name(config):
|
||||
|
||||
|
||||
def get_base_path(config):
|
||||
return os.path.join(os.path.dirname(CONFIG_PATH), get_name(config))
|
||||
return os.path.join(os.path.dirname(core.CONFIG_PATH), get_name(config))
|
||||
|
||||
|
||||
def discover_serial_ports():
|
||||
@ -47,8 +44,6 @@ def discover_serial_ports():
|
||||
|
||||
if not result:
|
||||
return None
|
||||
if len(result) == 1:
|
||||
return result[0]
|
||||
print(u"Found multiple serial port options, please choose one:")
|
||||
for i, (res, desc) in enumerate(zip(result, descs)):
|
||||
print(u" [{}] {} ({})".format(i, res, desc))
|
||||
@ -107,18 +102,24 @@ def run_miniterm(config, port):
|
||||
|
||||
def write_cpp(config):
|
||||
_LOGGER.info("Generating C++ source...")
|
||||
|
||||
add_task(core_to_code, config[CONF_ESPHOMEYAML])
|
||||
for domain in PRE_INITIALIZE:
|
||||
if domain == CONF_ESPHOMEYAML:
|
||||
continue
|
||||
if domain in config:
|
||||
add_component_task(domain, config[domain])
|
||||
add_task(get_component(domain).to_code, config[domain])
|
||||
|
||||
# Clear queue
|
||||
get_variable(None)
|
||||
add(RawStatement(''))
|
||||
|
||||
for domain, conf in config.iteritems():
|
||||
for domain, component, conf in iter_components(config):
|
||||
if domain in PRE_INITIALIZE:
|
||||
continue
|
||||
add_component_task(domain, conf)
|
||||
if not hasattr(component, 'to_code'):
|
||||
continue
|
||||
add_task(component.to_code, conf)
|
||||
|
||||
# Clear queue
|
||||
get_variable(None)
|
||||
@ -127,7 +128,10 @@ def write_cpp(config):
|
||||
|
||||
all_code = []
|
||||
for exp in _EXPRESSIONS:
|
||||
if helpers.SIMPLIFY and isinstance(exp, AssignmentExpression) and exp.obj.usages == 0:
|
||||
if core.SIMPLIFY:
|
||||
if isinstance(exp, Expression) and not exp.required:
|
||||
continue
|
||||
if isinstance(exp, AssignmentExpression) and not exp.obj.required:
|
||||
exp = exp.rhs
|
||||
all_code.append(unicode(statement(exp)))
|
||||
|
||||
@ -211,8 +215,6 @@ def setup_log():
|
||||
|
||||
|
||||
def main():
|
||||
global CONFIG_PATH
|
||||
|
||||
setup_log()
|
||||
|
||||
parser = argparse.ArgumentParser(prog='esphomeyaml')
|
||||
@ -260,13 +262,17 @@ def main():
|
||||
subparsers.add_parser('wizard', help="A helpful setup wizard that will guide "
|
||||
"you through setting up esphomeyaml.")
|
||||
|
||||
subparsers.add_parser('mqtt-fingerprint', help="Get the SSL fingerprint from a MQTT broker.")
|
||||
subparsers.add_parser('version', help="Print the esphomeyaml version and exit.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == 'wizard':
|
||||
return wizard.wizard(args.configuration)
|
||||
|
||||
CONFIG_PATH = args.configuration
|
||||
config = read_config(CONFIG_PATH)
|
||||
core.CONFIG_PATH = args.configuration
|
||||
|
||||
config = read_config(core.CONFIG_PATH)
|
||||
if config is None:
|
||||
return 1
|
||||
|
||||
@ -294,6 +300,8 @@ def main():
|
||||
return show_logs(config, args, port)
|
||||
elif args.command == 'clean-mqtt':
|
||||
return clean_mqtt(config, args)
|
||||
elif args.command == 'mqtt-fingerprint':
|
||||
return mqtt.get_fingerprint(config)
|
||||
elif args.command == 'run':
|
||||
exit_code = write_cpp(config)
|
||||
if exit_code != 0:
|
||||
@ -302,14 +310,17 @@ def main():
|
||||
if exit_code != 0:
|
||||
return exit_code
|
||||
_LOGGER.info(u"Successfully compiled program.")
|
||||
if args.no_logs:
|
||||
return 0
|
||||
port = args.upload_port or discover_serial_ports()
|
||||
exit_code = upload_program(config, args, port)
|
||||
if exit_code != 0:
|
||||
return exit_code
|
||||
_LOGGER.info(u"Successfully uploaded program.")
|
||||
if args.no_logs:
|
||||
return 0
|
||||
return show_logs(config, args, port)
|
||||
elif args.command == 'version':
|
||||
print(u"Version: {}".format(const.__version__))
|
||||
return 0
|
||||
print(u"Unknown command {}".format(args.command))
|
||||
return 1
|
||||
|
||||
|
@ -35,3 +35,7 @@ def to_code(config):
|
||||
ads1115 = Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
||||
if CONF_RATE in conf:
|
||||
add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]])))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_ADS1115_SENSOR'
|
||||
|
@ -4,10 +4,6 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED
|
||||
from esphomeyaml.helpers import add, setup_mqtt_component
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_INVERTED): cv.boolean,
|
||||
})
|
||||
|
||||
DEVICE_CLASSES = [
|
||||
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
|
||||
'heat', 'light', 'lock', 'moisture', 'motion', 'moving', 'occupancy',
|
||||
@ -17,13 +13,27 @@ DEVICE_CLASSES = [
|
||||
|
||||
DEVICE_CLASSES_MSG = "Unknown device class. Must be one of {}".format(', '.join(DEVICE_CLASSES))
|
||||
|
||||
MQTT_BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_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({
|
||||
|
||||
def setup_mqtt_binary_sensor(obj, config, skip_device_class=False):
|
||||
if not skip_device_class and CONF_DEVICE_CLASS in config:
|
||||
})
|
||||
|
||||
|
||||
def setup_binary_sensor(obj, config):
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
add(obj.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||
if CONF_INVERTED in config:
|
||||
add(obj.set_inverted(config[CONF_INVERTED]))
|
||||
|
||||
|
||||
def setup_mqtt_binary_sensor(obj, config):
|
||||
setup_mqtt_component(obj, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_BINARY_SENSOR'
|
||||
|
@ -3,7 +3,7 @@ import voluptuous as vol
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INVERTED, CONF_NAME, CONF_PIN
|
||||
from esphomeyaml.const import CONF_ID, CONF_INVERTED, CONF_NAME, CONF_PIN
|
||||
from esphomeyaml.helpers import App, add, exp_gpio_input_pin, variable
|
||||
|
||||
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
|
||||
@ -13,9 +13,13 @@ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_gpio_binary_sensor(exp_gpio_input_pin(config[CONF_PIN]),
|
||||
config[CONF_NAME], config.get(CONF_DEVICE_CLASS))
|
||||
gpio = variable('Application::SimpleBinarySensor', config[CONF_ID], rhs)
|
||||
rhs = App.make_gpio_binary_sensor(config[CONF_NAME], exp_gpio_input_pin(config[CONF_PIN]))
|
||||
gpio = variable('Application::MakeGPIOBinarySensor', config[CONF_ID], rhs)
|
||||
if CONF_INVERTED in config:
|
||||
add(gpio.Pgpio.set_inverted(config[CONF_INVERTED]))
|
||||
binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config, skip_device_class=True)
|
||||
binary_sensor.setup_binary_sensor(gpio.Pgpio, config)
|
||||
binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_GPIO_BINARY_SENSOR'
|
||||
|
@ -1,7 +1,9 @@
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.const import CONF_ID, CONF_NAME
|
||||
from esphomeyaml.helpers import App, Pvariable
|
||||
from esphomeyaml.helpers import App, variable
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('status_binary_sensor'): cv.register_variable_id,
|
||||
@ -10,5 +12,10 @@ PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_status_binary_sensor(config[CONF_NAME])
|
||||
gpio = Pvariable('binary_sensor::MQTTBinarySensorComponent', config[CONF_ID], rhs)
|
||||
binary_sensor.setup_mqtt_binary_sensor(gpio.Pmqtt, config)
|
||||
status = variable('Application::MakeStatusBinarySensor', config[CONF_ID], rhs)
|
||||
binary_sensor.setup_binary_sensor(status.Pstatus, config)
|
||||
binary_sensor.setup_mqtt_binary_sensor(status.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_STATUS_BINARY_SENSOR'
|
||||
|
@ -18,3 +18,7 @@ def to_code(config):
|
||||
for conf in config:
|
||||
rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL))
|
||||
Pvariable(DALLAS_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_DALLAS_SENSOR'
|
||||
|
15
esphomeyaml/components/debug.py
Normal file
15
esphomeyaml/components/debug.py
Normal file
@ -0,0 +1,15 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.helpers import App, add
|
||||
|
||||
DEPENDENCIES = ['logger']
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({})
|
||||
|
||||
|
||||
def to_code(config):
|
||||
add(App.make_debug_component())
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_DEBUG_COMPONENT'
|
42
esphomeyaml/components/deep_sleep.py
Normal file
42
esphomeyaml/components/deep_sleep.py
Normal file
@ -0,0 +1,42 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import config_validation as cv, pins
|
||||
from esphomeyaml.const import CONF_ID, CONF_RUN_CYCLES, CONF_RUN_DURATION, CONF_SLEEP_DURATION, \
|
||||
CONF_WAKEUP_PIN
|
||||
from esphomeyaml.helpers import App, Pvariable, add, exp_gpio_input_pin
|
||||
|
||||
|
||||
def validate_pin_number(value):
|
||||
valid_pins = [0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 39]
|
||||
if value not in valid_pins:
|
||||
raise vol.Invalid(u"Only pins {} support wakeup"
|
||||
u"".format(', '.join(str(x) for x in valid_pins)))
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID('deep_sleep'): cv.register_variable_id,
|
||||
vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period,
|
||||
vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.GPIO_INPUT_PIN_SCHEMA,
|
||||
pins.schema_validate_number(validate_pin_number)),
|
||||
vol.Optional(CONF_RUN_CYCLES): cv.positive_int,
|
||||
vol.Optional(CONF_RUN_DURATION): cv.positive_time_period,
|
||||
})
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_deep_sleep_component()
|
||||
deep_sleep = Pvariable('DeepSleepComponent', config[CONF_ID], rhs)
|
||||
if CONF_SLEEP_DURATION in config:
|
||||
add(deep_sleep.set_sleep_duration(config[CONF_SLEEP_DURATION]))
|
||||
if CONF_WAKEUP_PIN in config:
|
||||
pin = exp_gpio_input_pin(config[CONF_WAKEUP_PIN])
|
||||
add(deep_sleep.set_wakeup_pin(pin))
|
||||
if CONF_RUN_CYCLES in config:
|
||||
add(deep_sleep.set_run_cycles(config[CONF_RUN_CYCLES]))
|
||||
if CONF_RUN_DURATION in config:
|
||||
add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION]))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_DEEP_SLEEP'
|
@ -21,3 +21,7 @@ def setup_mqtt_fan(obj, config):
|
||||
if CONF_SPEED_COMMAND_TOPIC in config:
|
||||
add(obj.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC]))
|
||||
setup_mqtt_component(obj, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_FAN'
|
||||
|
@ -15,7 +15,7 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({
|
||||
def to_code(config):
|
||||
output = get_variable(config[CONF_OUTPUT])
|
||||
rhs = App.make_fan(config[CONF_NAME])
|
||||
fan_struct = variable('Application::FanStruct', config[CONF_ID], rhs)
|
||||
fan_struct = variable('Application::MakeFan', config[CONF_ID], rhs)
|
||||
add(fan_struct.Poutput.set_binary(output))
|
||||
if CONF_OSCILLATION_OUTPUT in config:
|
||||
oscillation_output = get_variable(config[CONF_OSCILLATION_OUTPUT])
|
||||
|
@ -24,7 +24,7 @@ PLATFORM_SCHEMA = fan.PLATFORM_SCHEMA.extend({
|
||||
def to_code(config):
|
||||
output = get_variable(config[CONF_OUTPUT])
|
||||
rhs = App.make_fan(config[CONF_NAME])
|
||||
fan_struct = variable('Application::FanStruct', config[CONF_ID], rhs)
|
||||
fan_struct = variable('Application::MakeFan', config[CONF_ID], rhs)
|
||||
if CONF_SPEED in config:
|
||||
speeds = config[CONF_SPEED]
|
||||
add(fan_struct.Poutput.set_speed(output, 0.0,
|
||||
|
@ -14,3 +14,7 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
|
||||
def to_code(config):
|
||||
add(App.init_i2c(config[CONF_SDA], config[CONF_SCL], config.get(CONF_FREQUENCY)))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_I2C'
|
||||
|
@ -21,3 +21,7 @@ def to_code(config):
|
||||
pin = exp_gpio_output_pin(conf[CONF_PIN])
|
||||
rhs = App.make_ir_transmitter(pin, conf.get(CONF_CARRIER_DUTY_PERCENT))
|
||||
Pvariable(IR_TRANSMITTER_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_IR_TRANSMITTER'
|
||||
|
@ -1,13 +1,16 @@
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH
|
||||
from esphomeyaml.helpers import add, setup_mqtt_component
|
||||
from esphomeyaml.helpers import add
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
||||
}).extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def setup_mqtt_light_component(obj, config):
|
||||
def setup_light_component(obj, config):
|
||||
if CONF_DEFAULT_TRANSITION_LENGTH in config:
|
||||
add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH]))
|
||||
setup_mqtt_component(obj, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_LIGHT'
|
||||
|
@ -4,7 +4,7 @@ import voluptuous as vol
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_OUTPUT
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.helpers import App, get_variable, variable, setup_mqtt_component
|
||||
|
||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('binary_light'): cv.register_variable_id,
|
||||
@ -15,5 +15,6 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
def to_code(config):
|
||||
output = get_variable(config[CONF_OUTPUT])
|
||||
rhs = App.make_binary_light(config[CONF_NAME], output)
|
||||
light_struct = variable('Application::LightStruct', config[CONF_ID], rhs)
|
||||
light.setup_mqtt_light_component(light_struct.Pmqtt, config)
|
||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||
light.setup_light_component(light_struct.Pstate, config)
|
||||
|
@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \
|
||||
CONF_NAME, CONF_OUTPUT
|
||||
from esphomeyaml.helpers import App, add, get_variable, variable
|
||||
from esphomeyaml.helpers import App, add, get_variable, variable, setup_mqtt_component
|
||||
|
||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('monochromatic_light'): cv.register_variable_id,
|
||||
@ -17,7 +17,8 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
def to_code(config):
|
||||
output = get_variable(config[CONF_OUTPUT])
|
||||
rhs = App.make_monochromatic_light(config[CONF_NAME], output)
|
||||
light_struct = variable('Application::LightStruct', config[CONF_ID], rhs)
|
||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||
if CONF_GAMMA_CORRECT in config:
|
||||
add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
||||
light.setup_mqtt_light_component(light_struct.Pmqtt, config)
|
||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||
light.setup_light_component(light_struct.Pstate, config)
|
||||
|
@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||
CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED
|
||||
from esphomeyaml.helpers import App, add, get_variable, variable
|
||||
from esphomeyaml.helpers import App, add, get_variable, variable, setup_mqtt_component
|
||||
|
||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('rgb_light'): cv.register_variable_id,
|
||||
@ -21,7 +21,8 @@ def to_code(config):
|
||||
green = get_variable(config[CONF_GREEN])
|
||||
blue = get_variable(config[CONF_BLUE])
|
||||
rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue)
|
||||
light_struct = variable('Application::LightStruct', config[CONF_ID], rhs)
|
||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||
if CONF_GAMMA_CORRECT in config:
|
||||
add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
||||
light.setup_mqtt_light_component(light_struct.Pmqtt, config)
|
||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||
light.setup_light_component(light_struct.Pstate, config)
|
||||
|
@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||
CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED, CONF_WHITE
|
||||
from esphomeyaml.helpers import App, get_variable, variable, add
|
||||
from esphomeyaml.helpers import App, add, get_variable, setup_mqtt_component, variable
|
||||
|
||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('rgbw_light'): cv.register_variable_id,
|
||||
@ -23,7 +23,8 @@ def to_code(config):
|
||||
blue = get_variable(config[CONF_BLUE])
|
||||
white = get_variable(config[CONF_WHITE])
|
||||
rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white)
|
||||
light_struct = variable('Application::LightStruct', config[CONF_ID], rhs)
|
||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||
if CONF_GAMMA_CORRECT in config:
|
||||
add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
||||
light.setup_mqtt_light_component(light_struct.Pmqtt, config)
|
||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||
light.setup_light_component(light_struct.Pstate, config)
|
||||
|
@ -2,20 +2,18 @@ import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER, CONF_LOGS, \
|
||||
CONF_LOG_TOPIC, CONF_TX_BUFFER_SIZE
|
||||
CONF_TX_BUFFER_SIZE
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, Pvariable, RawExpression, add, exp_empty_optional
|
||||
from esphomeyaml.helpers import App, Pvariable, RawExpression, add
|
||||
|
||||
LOG_LEVELS = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE']
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
is_log_level = vol.All(vol.Upper, vol.Any(*LOG_LEVELS))
|
||||
|
||||
CONFIG_SCHEMA = cv.ID_SCHEMA.extend({
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(CONF_LOGGER): cv.register_variable_id,
|
||||
vol.Optional(CONF_BAUD_RATE): cv.positive_int,
|
||||
vol.Optional(CONF_LOG_TOPIC): vol.Any(None, '', cv.publish_topic),
|
||||
vol.Optional(CONF_TX_BUFFER_SIZE): cv.positive_int,
|
||||
vol.Optional(CONF_LEVEL): is_log_level,
|
||||
vol.Optional(CONF_LOGS): vol.Schema({
|
||||
@ -33,16 +31,7 @@ def exp_log_level(level):
|
||||
|
||||
|
||||
def to_code(config):
|
||||
baud_rate = config.get(CONF_BAUD_RATE)
|
||||
if baud_rate is None and CONF_LOG_TOPIC in config:
|
||||
baud_rate = 115200
|
||||
log_topic = None
|
||||
if CONF_LOG_TOPIC in config:
|
||||
if not config[CONF_LOG_TOPIC]:
|
||||
log_topic = exp_empty_optional(u'std::string')
|
||||
else:
|
||||
log_topic = config[CONF_LOG_TOPIC]
|
||||
rhs = App.init_log(baud_rate, log_topic)
|
||||
rhs = App.init_log(config.get(CONF_BAUD_RATE))
|
||||
log = Pvariable(u'LogComponent', config[CONF_ID], rhs)
|
||||
if CONF_TX_BUFFER_SIZE in config:
|
||||
add(log.set_tx_buffer_size(config[CONF_TX_BUFFER_SIZE]))
|
||||
@ -56,7 +45,7 @@ def to_code(config):
|
||||
add(log.set_log_level(tag, exp_log_level(level)))
|
||||
|
||||
|
||||
def get_build_flags(config):
|
||||
def required_build_flags(config):
|
||||
if CONF_LEVEL in config:
|
||||
return u'-DESPHOMELIB_LOG_LEVEL={}'.format(esphomelib_log_level(config[CONF_LEVEL]))
|
||||
return u''
|
||||
return None
|
||||
|
@ -1,11 +1,14 @@
|
||||
import re
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_DISCOVERY, \
|
||||
CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_MQTT, CONF_PASSWORD, \
|
||||
CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_USERNAME, \
|
||||
CONF_WILL_MESSAGE, CONF_CLIENT_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, exp_empty_optional
|
||||
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_MQTT, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, CONF_TOPIC, \
|
||||
CONF_TOPIC_PREFIX, CONF_USERNAME, CONF_WILL_MESSAGE
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, StructInitializer, add, \
|
||||
exp_empty_optional, RawExpression
|
||||
|
||||
MQTT_WILL_BIRTH_SCHEMA = vol.Any(None, vol.Schema({
|
||||
vol.Required(CONF_TOPIC): cv.publish_topic,
|
||||
@ -19,7 +22,7 @@ def validate_broker(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 specify the static IP instead.")
|
||||
u" Please use the static IP instead.")
|
||||
if u':' in value:
|
||||
raise vol.Invalid(u"Please specify the port using the port: option")
|
||||
if not value:
|
||||
@ -27,7 +30,14 @@ def validate_broker(value):
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.ID_SCHEMA.extend({
|
||||
def validate_fingerprint(value):
|
||||
value = cv.string(value)
|
||||
if re.match(r'^[0-9a-f]{40}$', value) is None:
|
||||
raise vol.Invalid(u"fingerprint must be valid SHA1 hash")
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(CONF_MQTT): cv.register_variable_id,
|
||||
vol.Required(CONF_BROKER): validate_broker,
|
||||
vol.Optional(CONF_PORT, default=1883): cv.port,
|
||||
@ -40,6 +50,9 @@ CONFIG_SCHEMA = cv.ID_SCHEMA.extend({
|
||||
vol.Optional(CONF_BIRTH_MESSAGE): MQTT_WILL_BIRTH_SCHEMA,
|
||||
vol.Optional(CONF_WILL_MESSAGE): MQTT_WILL_BIRTH_SCHEMA,
|
||||
vol.Optional(CONF_TOPIC_PREFIX): cv.publish_topic,
|
||||
vol.Optional(CONF_LOG_TOPIC): cv.publish_topic,
|
||||
vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266,
|
||||
cv.ensure_list, [validate_fingerprint]),
|
||||
})
|
||||
|
||||
|
||||
@ -74,3 +87,15 @@ def to_code(config):
|
||||
add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX]))
|
||||
if CONF_CLIENT_ID in config:
|
||||
add(mqtt.set_client_id(config[CONF_CLIENT_ID]))
|
||||
if CONF_LOG_TOPIC in config:
|
||||
add(mqtt.set_log_topic(config[CONF_LOG_TOPIC]))
|
||||
if CONF_SSL_FINGERPRINTS in config:
|
||||
for fingerprint in config[CONF_SSL_FINGERPRINTS]:
|
||||
arr = [RawExpression("0x{}".format(fingerprint[i:i + 2])) for i in range(0, 40, 2)]
|
||||
add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False)))
|
||||
|
||||
|
||||
def required_build_flags(config):
|
||||
if CONF_SSL_FINGERPRINTS in config:
|
||||
return '-DASYNC_TCP_SSL_ENABLED=1'
|
||||
return None
|
||||
|
@ -4,14 +4,15 @@ import logging
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \
|
||||
ESP_PLATFORM_ESP8266, ESP_PLATFORM_ESP32
|
||||
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, Pvariable, add
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_SCHEMA = cv.ID_SCHEMA.extend({
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(CONF_OTA): cv.register_variable_id,
|
||||
vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
|
||||
# TODO Num attempts + wait time
|
||||
@ -33,12 +34,16 @@ def to_code(config):
|
||||
def get_port(config):
|
||||
if CONF_PORT in config[CONF_OTA]:
|
||||
return config[CONF_OTA][CONF_PORT]
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
return 3232
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
return 8266
|
||||
raise ESPHomeYAMLError(u"Invalid ESP Platform for ESP OTA port.")
|
||||
|
||||
|
||||
def get_auth(config):
|
||||
return config[CONF_OTA].get(CONF_PASSWORD, '')
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_OTA'
|
||||
|
@ -23,3 +23,7 @@ def setup_output_platform(obj, config, skip_power_supply=False):
|
||||
add(obj.set_power_supply(power_supply))
|
||||
if CONF_MAX_POWER in config:
|
||||
add(obj.set_max_power(config[CONF_MAX_POWER]))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_OUTPUT'
|
||||
|
@ -2,23 +2,31 @@ import voluptuous as vol
|
||||
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.const import CONF_ID, CONF_PIN, \
|
||||
ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.const import CONF_ID, CONF_PIN, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, Pvariable, exp_gpio_output_pin, get_gpio_pin_number
|
||||
from esphomeyaml.helpers import App, Pvariable, exp_gpio_output_pin
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP8266]
|
||||
|
||||
|
||||
def valid_pwm_pin(value):
|
||||
if value >= 16:
|
||||
raise ESPHomeYAMLError(u"ESP8266: Only pins 0-16 support PWM.")
|
||||
return value
|
||||
|
||||
|
||||
PLATFORM_SCHEMA = output.FLOAT_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
||||
vol.Required(CONF_PIN): vol.All(pins.GPIO_OUTPUT_PIN_SCHEMA,
|
||||
pins.schema_validate_number(valid_pwm_pin)),
|
||||
})
|
||||
|
||||
|
||||
def to_code(config):
|
||||
if get_gpio_pin_number(config[CONF_PIN]) >= 16:
|
||||
# Too difficult to do in config validation
|
||||
raise ESPHomeYAMLError(u"ESP8266: Only pins 0-16 support PWM.")
|
||||
pin = exp_gpio_output_pin(config[CONF_PIN])
|
||||
rhs = App.make_esp8266_pwm_output(pin)
|
||||
gpio = Pvariable('output::ESP8266PWMOutput', config[CONF_ID], rhs)
|
||||
output.setup_output_platform(gpio, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_ESP8266_PWM_OUTPUT'
|
||||
|
@ -15,3 +15,7 @@ def to_code(config):
|
||||
rhs = App.make_gpio_output(pin)
|
||||
gpio = Pvariable('output::GPIOBinaryOutputComponent', config[CONF_ID], rhs)
|
||||
output.setup_output_platform(gpio, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_GPIO_OUTPUT'
|
||||
|
@ -36,3 +36,7 @@ def to_code(config):
|
||||
if CONF_CHANNEL in config:
|
||||
add(ledc.set_channel(config[CONF_CHANNEL]))
|
||||
output.setup_output_platform(ledc, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_LEDC_OUTPUT'
|
||||
|
@ -23,3 +23,7 @@ def to_code(config):
|
||||
rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply)
|
||||
out = Pvariable('output::PCA9685OutputComponent::Channel', config[CONF_ID], rhs)
|
||||
output.setup_output_platform(out, config, skip_power_supply=True)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_PCA9685_OUTPUT'
|
||||
|
@ -31,3 +31,7 @@ def to_code(config):
|
||||
phase_balancer = RawExpression(u'PCA9685_PhaseBalancer_{}'.format(
|
||||
conf[CONF_PHASE_BALANCER]))
|
||||
add(pca9685.set_phase_balancer(phase_balancer))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_PCA9685_OUTPUT'
|
||||
|
@ -23,3 +23,7 @@ def to_code(config):
|
||||
add(psu.set_enable_time(conf[CONF_ENABLE_TIME]))
|
||||
if CONF_KEEP_ON_TIME in conf:
|
||||
add(psu.set_keep_on_time(conf[CONF_KEEP_ON_TIME]))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_OUTPUT'
|
||||
|
@ -3,8 +3,8 @@ import voluptuous as vol
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_EXPIRE_AFTER, \
|
||||
CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, CONF_FILTER_NAN, CONF_FILTER_OUT, CONF_ICON, \
|
||||
CONF_ID, CONF_LAMBDA, CONF_MULTIPLY, CONF_NAME, CONF_OFFSET, CONF_SEND_EVERY, \
|
||||
CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE
|
||||
CONF_LAMBDA, CONF_MQTT_ID, CONF_MULTIPLY, CONF_NAME, CONF_OFFSET, CONF_SEND_EVERY, \
|
||||
CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE, CONF_ID
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \
|
||||
setup_mqtt_component
|
||||
|
||||
@ -13,7 +13,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
})
|
||||
|
||||
FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.Any(
|
||||
# TODO Fix weird voluptuous error messages
|
||||
vol.Schema({vol.Required(CONF_OFFSET): vol.Coerce(float)}),
|
||||
vol.Schema({vol.Required(CONF_MULTIPLY): vol.Coerce(float)}),
|
||||
vol.Schema({vol.Required(CONF_FILTER_OUT): vol.Coerce(float)}),
|
||||
@ -43,7 +42,7 @@ MQTT_SENSOR_SCHEMA = vol.Schema({
|
||||
})
|
||||
|
||||
MQTT_SENSOR_ID_SCHEMA = MQTT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID('mqtt_sensor'): cv.register_variable_id,
|
||||
cv.GenerateID('mqtt_sensor', CONF_MQTT_ID): cv.register_variable_id,
|
||||
})
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
@ -72,30 +71,38 @@ def setup_filter(config):
|
||||
conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE]
|
||||
return ExponentialMovingAverageFilter(conf[CONF_ALPHA], conf[CONF_SEND_EVERY])
|
||||
if CONF_LAMBDA in config:
|
||||
s = '[](float x) -> Optional<float> {{ return {}; }}'.format(config[CONF_LAMBDA])
|
||||
s = u'[](float x) -> Optional<float> {{ return {}; }}'.format(config[CONF_LAMBDA])
|
||||
return LambdaFilter(RawExpression(s))
|
||||
raise ValueError("Filter unsupported: {}".format(config))
|
||||
raise ValueError(u"Filter unsupported: {}".format(config))
|
||||
|
||||
|
||||
def setup_mqtt_sensor_component(obj, config):
|
||||
if CONF_EXPIRE_AFTER in config:
|
||||
if config[CONF_EXPIRE_AFTER] is None:
|
||||
add(obj.disable_expire_after())
|
||||
else:
|
||||
add(obj.set_expire_after(config[CONF_EXPIRE_AFTER]))
|
||||
setup_mqtt_component(obj, config)
|
||||
|
||||
|
||||
def setup_sensor(obj, config):
|
||||
if CONF_UNIT_OF_MEASUREMENT in config:
|
||||
add(obj.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
|
||||
if CONF_ICON in config:
|
||||
add(obj.set_icon(config[CONF_ICON]))
|
||||
if CONF_ACCURACY_DECIMALS in config:
|
||||
add(obj.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
|
||||
if CONF_EXPIRE_AFTER in config:
|
||||
if config[CONF_EXPIRE_AFTER] is None:
|
||||
add(obj.disable_expire_after())
|
||||
else:
|
||||
add(obj.set_expire_after(config[CONF_EXPIRE_AFTER]))
|
||||
if CONF_FILTERS in config:
|
||||
filters = [setup_filter(x) for x in config[CONF_FILTERS]]
|
||||
add(obj.set_filters(ArrayInitializer(*filters)))
|
||||
setup_mqtt_component(obj, config)
|
||||
|
||||
|
||||
def make_mqtt_sensor_for(exp, config):
|
||||
rhs = App.make_mqtt_sensor_for(exp, config[CONF_NAME])
|
||||
mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_ID], rhs)
|
||||
def register_sensor(var, config):
|
||||
setup_sensor(var, config)
|
||||
rhs = App.register_sensor(var)
|
||||
mqtt_sensor = Pvariable('sensor::MQTTSensorComponent', config[CONF_MQTT_ID], rhs)
|
||||
setup_mqtt_sensor_component(mqtt_sensor, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_SENSOR'
|
||||
|
@ -25,11 +25,16 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_adc_sensor(config[CONF_PIN], config[CONF_NAME],
|
||||
rhs = App.make_adc_sensor(config[CONF_NAME], config[CONF_PIN],
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
make = variable('Application::MakeADCSensor', config[CONF_ID], rhs)
|
||||
adc = make.Padc
|
||||
if CONF_ATTENUATION in config:
|
||||
attenuation = ATTENUATION_MODES[config[CONF_ATTENUATION]]
|
||||
add(adc.set_attenuation(RawExpression(attenuation)))
|
||||
sensor.setup_sensor(adc, config)
|
||||
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_ADC_SENSOR'
|
||||
|
@ -2,8 +2,9 @@ import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import get_variable, RawExpression
|
||||
from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_UPDATE_INTERVAL, \
|
||||
CONF_NAME, CONF_ID
|
||||
from esphomeyaml.helpers import RawExpression, get_variable, Pvariable
|
||||
|
||||
DEPENDENCIES = ['ads1115']
|
||||
|
||||
@ -40,6 +41,7 @@ def validate_gain(value):
|
||||
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('ads1115_sensor'): cv.register_variable_id,
|
||||
vol.Required(CONF_MULTIPLEXER): vol.All(vol.Upper, vol.Any(*list(MUX.keys()))),
|
||||
vol.Required(CONF_GAIN): validate_gain,
|
||||
vol.Optional(CONF_ADS1115_ID): cv.variable_id,
|
||||
@ -52,5 +54,10 @@ def to_code(config):
|
||||
|
||||
mux = RawExpression(MUX[config[CONF_MULTIPLEXER]])
|
||||
gain = RawExpression(GAIN[config[CONF_GAIN]])
|
||||
sensor_ = hub.get_sensor(mux, gain, config.get(CONF_UPDATE_INTERVAL))
|
||||
sensor.make_mqtt_sensor_for(sensor_, config)
|
||||
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(sensor_, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_ADS1115_SENSOR'
|
||||
|
@ -22,8 +22,14 @@ def to_code(config):
|
||||
rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_PRESSURE][CONF_NAME],
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
bmp = variable('Application::MakeBMP085Component', config[CONF_ID], rhs)
|
||||
bmp = variable('Application::MakeBMP085Sensor', config[CONF_ID], rhs)
|
||||
if CONF_ADDRESS in config:
|
||||
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_pressure_sensor(), config[CONF_PRESSURE])
|
||||
sensor.setup_mqtt_sensor_component(bmp.Pmqtt_pressure, config[CONF_PRESSURE])
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_BMP085_SENSOR'
|
||||
|
@ -3,11 +3,13 @@ import voluptuous as vol
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.components.dallas import DALLAS_COMPONENT_CLASS
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_RESOLUTION, \
|
||||
CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import HexIntLiteral, get_variable
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \
|
||||
CONF_RESOLUTION, \
|
||||
CONF_UPDATE_INTERVAL, CONF_ID
|
||||
from esphomeyaml.helpers import HexIntLiteral, get_variable, Pvariable
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('dallas_sensor'): cv.register_variable_id,
|
||||
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
|
||||
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
|
||||
vol.Optional(CONF_DALLAS_ID): cv.variable_id,
|
||||
@ -23,9 +25,14 @@ def to_code(config):
|
||||
|
||||
if CONF_ADDRESS in config:
|
||||
address = HexIntLiteral(config[CONF_ADDRESS])
|
||||
sensor_ = hub.Pget_sensor_by_address(address, update_interval,
|
||||
rhs = hub.Pget_sensor_by_address(config[CONF_NAME], address, update_interval,
|
||||
config.get(CONF_RESOLUTION))
|
||||
else:
|
||||
sensor_ = hub.Pget_sensor_by_index(config[CONF_INDEX], update_interval,
|
||||
config.get(CONF_RESOLUTION))
|
||||
sensor.make_mqtt_sensor_for(sensor_, config)
|
||||
rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX],
|
||||
update_interval, config.get(CONF_RESOLUTION))
|
||||
sensor_ = Pvariable('sensor::DallasTemperatureSensor', config[CONF_ID], rhs)
|
||||
sensor.register_sensor(sensor_, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_DALLAS_SENSOR'
|
||||
|
@ -21,11 +21,18 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_dht_sensor(config[CONF_PIN], config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_HUMIDITY][CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
|
||||
dht = variable('Application::MakeDHTComponent', config[CONF_ID], rhs)
|
||||
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_HUMIDITY][CONF_NAME],
|
||||
config[CONF_PIN], config.get(CONF_UPDATE_INTERVAL))
|
||||
dht = variable('Application::MakeDHTSensor', config[CONF_ID], rhs)
|
||||
if CONF_MODEL in config:
|
||||
model = RawExpression('DHT::{}'.format(config[CONF_MODEL]))
|
||||
add(dht.Pdht.set_dht_model(model))
|
||||
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_humidity_sensor(), config[CONF_HUMIDITY])
|
||||
sensor.setup_mqtt_sensor_component(dht.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_DHT_SENSOR'
|
||||
|
@ -21,6 +21,12 @@ def to_code(config):
|
||||
rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_HUMIDITY][CONF_NAME],
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
hdc1080 = variable('Application::MakeHDC1080Component', config[CONF_ID], rhs)
|
||||
hdc1080 = variable('Application::MakeHDC1080Sensor', config[CONF_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_humidity_sensor(), config[CONF_HUMIDITY])
|
||||
sensor.setup_mqtt_sensor_component(hdc1080.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_HDC1080_SENSOR'
|
||||
|
@ -21,6 +21,12 @@ def to_code(config):
|
||||
rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_HUMIDITY][CONF_NAME],
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
htu21d = variable('Application::MakeHTU21DComponent', config[CONF_ID], rhs)
|
||||
htu21d = variable('Application::MakeHTU21DSensor', config[CONF_ID], rhs)
|
||||
sensor.setup_sensor(htu21d.Phtu21d.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
|
||||
sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_temperature, config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(htu21d.Phtu21d.Pget_humidity_sensor(), config[CONF_HUMIDITY])
|
||||
sensor.setup_mqtt_sensor_component(htu21d.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_HTU21D_SENSOR'
|
||||
|
@ -41,9 +41,9 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_pulse_counter_sensor(config[CONF_PIN], config[CONF_NAME],
|
||||
rhs = App.make_pulse_counter_sensor(config[CONF_NAME], config[CONF_PIN],
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
make = variable('Application::MakePulseCounter', config[CONF_ID], rhs)
|
||||
make = variable('Application::MakePulseCounterSensor', config[CONF_ID], rhs)
|
||||
pcnt = make.Ppcnt
|
||||
if CONF_PULL_MODE in config:
|
||||
pull_mode = GPIO_PULL_MODES[config[CONF_PULL_MODE]]
|
||||
@ -55,4 +55,9 @@ def to_code(config):
|
||||
add(pcnt.set_edge_mode(RawExpression(rising_edge), RawExpression(falling_edge)))
|
||||
if CONF_INTERNAL_FILTER in config:
|
||||
add(pcnt.set_filter(config[CONF_INTERNAL_FILTER]))
|
||||
sensor.setup_sensor(pcnt, config)
|
||||
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_PULSE_COUNTER_SENSOR'
|
||||
|
@ -21,7 +21,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
def to_code(config):
|
||||
trigger = exp_gpio_output_pin(config[CONF_TRIGGER_PIN])
|
||||
echo = exp_gpio_input_pin(config[CONF_ECHO_PIN])
|
||||
rhs = App.make_ultrasonic_sensor(trigger, echo, config[CONF_NAME],
|
||||
rhs = App.make_ultrasonic_sensor(config[CONF_NAME], trigger, echo,
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
make = variable('Application::MakeUltrasonicSensor', config[CONF_ID], rhs)
|
||||
ultrasonic = make.Pultrasonic
|
||||
@ -29,4 +29,9 @@ def to_code(config):
|
||||
add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT_TIME]))
|
||||
elif CONF_TIMEOUT_METER in config:
|
||||
add(ultrasonic.set_timeout_m(config[CONF_TIMEOUT_METER]))
|
||||
sensor.setup_sensor(ultrasonic, config)
|
||||
sensor.setup_mqtt_sensor_component(make.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_ULTRASONIC_SENSOR'
|
||||
|
@ -1,7 +1,7 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_NAME
|
||||
from esphomeyaml.const import CONF_ICON, CONF_ID, CONF_NAME, CONF_MQTT_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, add, setup_mqtt_component
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
@ -12,14 +12,26 @@ MQTT_SWITCH_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
vol.Optional(CONF_ICON): cv.icon,
|
||||
})
|
||||
|
||||
MQTT_SWITCH_ID_SCHEMA = MQTT_SWITCH_SCHEMA.extend({
|
||||
cv.GenerateID('mqtt_switch', CONF_MQTT_ID): cv.register_variable_id,
|
||||
})
|
||||
|
||||
|
||||
def setup_mqtt_switch(obj, config):
|
||||
if CONF_ICON in config:
|
||||
add(obj.set_icon(config[CONF_ICON]))
|
||||
setup_mqtt_component(obj, config)
|
||||
|
||||
|
||||
def make_mqtt_switch_for(exp, config):
|
||||
rhs = App.make_mqtt_switch_for(exp, config[CONF_NAME])
|
||||
mqtt_switch = Pvariable('switch_::MQTTSwitchComponent', config[CONF_ID], rhs)
|
||||
def setup_switch(obj, config):
|
||||
if CONF_ICON in config:
|
||||
add(obj.set_icon(config[CONF_ICON]))
|
||||
|
||||
|
||||
def register_switch(var, config):
|
||||
setup_switch(var, config)
|
||||
rhs = App.register_switch(var)
|
||||
mqtt_switch = Pvariable('switch_::MQTTSwitchComponent', config[CONF_MQTT_ID], rhs)
|
||||
setup_mqtt_switch(mqtt_switch, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_SWITCH'
|
||||
|
@ -13,6 +13,11 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_gpio_switch(exp_gpio_output_pin(config[CONF_PIN]), config[CONF_NAME])
|
||||
gpio = variable('Application::GPIOSwitchStruct', config[CONF_ID], rhs)
|
||||
rhs = App.make_gpio_switch(config[CONF_NAME], exp_gpio_output_pin(config[CONF_PIN]))
|
||||
gpio = variable('Application::MakeGPIOSwitch', config[CONF_ID], rhs)
|
||||
switch.setup_switch(gpio.Pswitch_, config)
|
||||
switch.setup_mqtt_switch(gpio.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_GPIO_SWITCH'
|
||||
|
@ -5,12 +5,12 @@ from esphomeyaml.components import switch
|
||||
from esphomeyaml.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_COMMAND, CONF_DATA, CONF_IR_TRANSMITTER_ID, \
|
||||
CONF_LG, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_REPEAT, CONF_SONY, CONF_TIMES, \
|
||||
CONF_WAIT_TIME_US, CONF_RAW, CONF_CARRIER_FREQUENCY
|
||||
CONF_WAIT_TIME_US, CONF_RAW, CONF_CARRIER_FREQUENCY, CONF_NAME, CONF_ID
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import HexIntLiteral, MockObj, get_variable, ArrayInitializer
|
||||
from esphomeyaml.helpers import HexIntLiteral, MockObj, get_variable, ArrayInitializer, Pvariable
|
||||
|
||||
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('ir_transmitter'): cv.register_variable_id,
|
||||
cv.GenerateID('ir_transmitter_switch'): cv.register_variable_id,
|
||||
vol.Exclusive(CONF_NEC, 'code'): vol.Schema({
|
||||
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
||||
vol.Required(CONF_COMMAND): cv.hex_uint16_t,
|
||||
@ -36,7 +36,7 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_WAIT_TIME_US): cv.uint32_t,
|
||||
})),
|
||||
vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id,
|
||||
}).extend(switch.MQTT_SWITCH_SCHEMA.schema)
|
||||
}).extend(switch.MQTT_SWITCH_ID_SCHEMA.schema)
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
@ -86,4 +86,11 @@ def exp_send_data(config):
|
||||
def to_code(config):
|
||||
ir = get_variable(config.get(CONF_IR_TRANSMITTER_ID), IR_TRANSMITTER_COMPONENT_CLASS)
|
||||
send_data = exp_send_data(config)
|
||||
switch.make_mqtt_switch_for(ir.create_transmitter(send_data), config)
|
||||
rhs = ir.create_transmitter(config[CONF_NAME], send_data)
|
||||
switch_ = Pvariable(IR_TRANSMITTER_COMPONENT_CLASS + '::DataTransmitter', config[CONF_ID],
|
||||
rhs)
|
||||
switch.register_switch(switch_, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_IR_TRANSMITTER'
|
||||
|
@ -1,7 +1,7 @@
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import switch
|
||||
from esphomeyaml.const import CONF_ID, CONF_NAME
|
||||
from esphomeyaml.helpers import App, Pvariable
|
||||
from esphomeyaml.helpers import App, variable
|
||||
|
||||
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID('restart_switch'): cv.register_variable_id,
|
||||
@ -10,5 +10,10 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_restart_switch(config[CONF_NAME])
|
||||
mqtt = Pvariable('switch_::MQTTSwitchComponent', config[CONF_ID], rhs)
|
||||
switch.setup_mqtt_switch(mqtt, config)
|
||||
restart = variable('Application::MakeRestartSwitch', config[CONF_ID], rhs)
|
||||
switch.setup_switch(restart.Prestart, config)
|
||||
switch.setup_mqtt_switch(restart.Pmqtt, config)
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_RESTART_SWITCH'
|
||||
|
29
esphomeyaml/components/web_server.py
Normal file
29
esphomeyaml/components/web_server.py
Normal file
@ -0,0 +1,29 @@
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID
|
||||
from esphomeyaml.helpers import App, add, Pvariable
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID('web_server'): cv.register_variable_id,
|
||||
vol.Optional(CONF_PORT): cv.port,
|
||||
vol.Optional(CONF_CSS_URL): vol.Url,
|
||||
vol.Optional(CONF_JS_URL): vol.Url,
|
||||
})
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.init_web_server(config.get(CONF_PORT))
|
||||
web_server = Pvariable('WebServer', config[CONF_ID], rhs)
|
||||
if CONF_CSS_URL in config:
|
||||
add(web_server.set_css_url(config[CONF_CSS_URL]))
|
||||
if CONF_JS_URL in config:
|
||||
add(web_server.set_js_url(config[CONF_JS_URL]))
|
||||
|
||||
|
||||
def build_flags(config):
|
||||
return '-DUSE_WEB_SERVER'
|
@ -1,25 +1,47 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_DNS1, CONF_DNS2, CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, \
|
||||
CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, CONF_WIFI
|
||||
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
|
||||
from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add
|
||||
|
||||
CONFIG_SCHEMA = cv.ID_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_WIFI): cv.register_variable_id,
|
||||
vol.Required(CONF_SSID): cv.ssid,
|
||||
vol.Optional(CONF_PASSWORD): cv.string,
|
||||
vol.Optional(CONF_MANUAL_IP): vol.Schema({
|
||||
|
||||
def validate_password(value):
|
||||
value = cv.string(value)
|
||||
if not value:
|
||||
return value
|
||||
if len(value) < 8:
|
||||
raise vol.Invalid(u"WPA password must be at least 8 characters long")
|
||||
if len(value) > 63:
|
||||
raise vol.Invalid(u"WPA password must be at most 63 characters long")
|
||||
return value
|
||||
|
||||
|
||||
AP_MANUAL_IP_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_STATIC_IP): cv.ipv4,
|
||||
vol.Required(CONF_GATEWAY): cv.ipv4,
|
||||
vol.Required(CONF_SUBNET): cv.ipv4,
|
||||
})
|
||||
|
||||
STA_MANUAL_IP_SCHEMA = AP_MANUAL_IP_SCHEMA.extend({
|
||||
vol.Inclusive(CONF_DNS1, 'dns'): cv.ipv4,
|
||||
vol.Inclusive(CONF_DNS2, 'dns'): cv.ipv4,
|
||||
})
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID('wifi'): cv.register_variable_id,
|
||||
vol.Optional(CONF_SSID): cv.ssid,
|
||||
vol.Optional(CONF_PASSWORD): validate_password,
|
||||
vol.Optional(CONF_MANUAL_IP): STA_MANUAL_IP_SCHEMA,
|
||||
vol.Optional(CONF_AP): vol.Schema({
|
||||
vol.Required(CONF_SSID): cv.ssid,
|
||||
vol.Optional(CONF_PASSWORD): validate_password,
|
||||
vol.Optional(CONF_CHANNEL): vol.All(cv.positive_int, vol.Range(min=1, max=14)),
|
||||
vol.Optional(CONF_MANUAL_IP): AP_MANUAL_IP_SCHEMA,
|
||||
}),
|
||||
vol.Optional(CONF_HOSTNAME): cv.hostname,
|
||||
})
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
IPAddress = MockObj('IPAddress')
|
||||
|
||||
@ -30,19 +52,38 @@ def safe_ip(ip):
|
||||
return IPAddress(*ip.args)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD))
|
||||
wifi = Pvariable('WiFiComponent', config[CONF_ID], rhs)
|
||||
if CONF_MANUAL_IP in config:
|
||||
manual_ip = config[CONF_MANUAL_IP]
|
||||
exp = StructInitializer(
|
||||
def manual_ip(config):
|
||||
return StructInitializer(
|
||||
'ManualIP',
|
||||
('static_ip', safe_ip(manual_ip[CONF_STATIC_IP])),
|
||||
('gateway', safe_ip(manual_ip[CONF_GATEWAY])),
|
||||
('subnet', safe_ip(manual_ip[CONF_SUBNET])),
|
||||
('dns1', safe_ip(manual_ip.get(CONF_DNS1))),
|
||||
('dns2', safe_ip(manual_ip.get(CONF_DNS2))),
|
||||
('static_ip', safe_ip(config[CONF_STATIC_IP])),
|
||||
('gateway', safe_ip(config[CONF_GATEWAY])),
|
||||
('subnet', safe_ip(config[CONF_SUBNET])),
|
||||
('dns1', safe_ip(config.get(CONF_DNS1))),
|
||||
('dns2', safe_ip(config.get(CONF_DNS2))),
|
||||
)
|
||||
add(wifi.set_manual_ip(exp))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
sta = CONF_SSID in config
|
||||
ap = CONF_AP in config
|
||||
if sta:
|
||||
rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD))
|
||||
else:
|
||||
rhs = App.init_wifi()
|
||||
wifi = Pvariable('WiFiComponent', config[CONF_ID], rhs)
|
||||
|
||||
if sta and CONF_MANUAL_IP in config:
|
||||
add(wifi.set_sta_manual_ip(manual_ip(config[CONF_MANUAL_IP])))
|
||||
|
||||
if ap:
|
||||
conf = config[CONF_AP]
|
||||
password = config.get(CONF_PASSWORD)
|
||||
if password is None and CONF_CHANNEL in conf:
|
||||
password = u""
|
||||
add(wifi.set_ap(conf[CONF_SSID], password, conf.get(CONF_CHANNEL)))
|
||||
|
||||
if CONF_MANUAL_IP in conf:
|
||||
add(wifi.set_ap_manual_ip(manual_ip(conf[CONF_MANUAL_IP])))
|
||||
|
||||
if CONF_HOSTNAME in config:
|
||||
add(wifi.set_hostname(config[CONF_HOSTNAME]))
|
||||
|
@ -8,13 +8,12 @@ import voluptuous as vol
|
||||
from voluptuous.humanize import humanize_error
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import helpers, yaml_util
|
||||
from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_MQTT, \
|
||||
CONF_NAME, \
|
||||
CONF_PLATFORM, CONF_SIMPLIFY, CONF_WIFI, ESP_PLATFORMS, ESP_PLATFORM_ESP32, \
|
||||
ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml import core, yaml_util
|
||||
from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \
|
||||
CONF_PLATFORM, CONF_SIMPLIFY, CONF_USE_BUILD_FLAGS, CONF_WIFI, ESP_PLATFORMS, \
|
||||
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, add, add_task, color
|
||||
from esphomeyaml.helpers import App, add, color
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -22,15 +21,15 @@ DEFAULT_LIBRARY_URI = u'esphomelib@1.2.1'
|
||||
|
||||
CORE_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_NAME): cv.valid_name,
|
||||
vol.Required(CONF_PLATFORM): vol.All(
|
||||
vol.Upper, vol.Any(ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266)),
|
||||
vol.Required(CONF_PLATFORM): cv.string,
|
||||
vol.Required(CONF_BOARD): cv.string,
|
||||
vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string,
|
||||
vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean,
|
||||
vol.Optional(CONF_USE_BUILD_FLAGS, default=False): cv.boolean,
|
||||
})
|
||||
|
||||
REQUIRED_COMPONENTS = [
|
||||
CONF_ESPHOMEYAML, CONF_WIFI, CONF_MQTT
|
||||
CONF_ESPHOMEYAML, CONF_WIFI
|
||||
]
|
||||
|
||||
_COMPONENT_CACHE = {}
|
||||
@ -66,8 +65,17 @@ def is_platform_component(component):
|
||||
return hasattr(component, 'PLATFORM_SCHEMA')
|
||||
|
||||
|
||||
def validate_schema(config, schema):
|
||||
return schema(config)
|
||||
def iter_components(config):
|
||||
for domain, conf in config.iteritems():
|
||||
if domain == CONF_ESPHOMEYAML:
|
||||
continue
|
||||
component = get_component(domain)
|
||||
yield domain, component, conf
|
||||
if is_platform_component(component):
|
||||
for p_config in conf:
|
||||
p_name = u"{}.{}".format(domain, p_config[CONF_PLATFORM])
|
||||
platform = get_component(p_name)
|
||||
yield p_name, platform, p_config
|
||||
|
||||
|
||||
class Config(OrderedDict):
|
||||
@ -96,7 +104,7 @@ def validate_config(config):
|
||||
result.add_error(_format_config_error(ex, domain, config), domain, config)
|
||||
|
||||
try:
|
||||
result[CONF_ESPHOMEYAML] = validate_schema(config[CONF_ESPHOMEYAML], CORE_SCHEMA)
|
||||
result[CONF_ESPHOMEYAML] = CORE_SCHEMA(config[CONF_ESPHOMEYAML])
|
||||
except vol.Invalid as ex:
|
||||
_comp_error(ex, CONF_ESPHOMEYAML, config)
|
||||
|
||||
@ -111,8 +119,8 @@ def validate_config(config):
|
||||
continue
|
||||
|
||||
esp_platforms = getattr(component, 'ESP_PLATFORMS', ESP_PLATFORMS)
|
||||
if cv.ESP_PLATFORM not in esp_platforms:
|
||||
result.add_error(u"Component {} doesn't support {}.".format(domain, cv.ESP_PLATFORM))
|
||||
if core.ESP_PLATFORM not in esp_platforms:
|
||||
result.add_error(u"Component {} doesn't support {}.".format(domain, core.ESP_PLATFORM))
|
||||
continue
|
||||
|
||||
success = True
|
||||
@ -129,7 +137,7 @@ def validate_config(config):
|
||||
validated = component.CONFIG_SCHEMA(conf)
|
||||
result[domain] = validated
|
||||
except vol.Invalid as ex:
|
||||
_comp_error(ex, domain, config)
|
||||
_comp_error(ex, domain, conf)
|
||||
continue
|
||||
|
||||
if not hasattr(component, 'PLATFORM_SCHEMA'):
|
||||
@ -138,7 +146,7 @@ def validate_config(config):
|
||||
platforms = []
|
||||
for p_config in conf:
|
||||
if not isinstance(p_config, dict):
|
||||
result.add_error(u"Platform schemas mus have 'platform:' key")
|
||||
result.add_error(u"Platform schemas must have 'platform:' key")
|
||||
continue
|
||||
p_name = p_config.get(u'platform')
|
||||
if p_name is None:
|
||||
@ -149,6 +157,16 @@ def validate_config(config):
|
||||
result.add_error(u"Platform not found: {}.{}")
|
||||
continue
|
||||
|
||||
success = True
|
||||
dependencies = getattr(platform, 'DEPENDENCIES', [])
|
||||
for dependency in dependencies:
|
||||
if dependency not in _ALL_COMPONENTS:
|
||||
result.add_error(u"Platform {}.{} requires {}".format(domain, p_name,
|
||||
dependency))
|
||||
success = False
|
||||
if not success:
|
||||
continue
|
||||
|
||||
if hasattr(platform, u'PLATFORM_SCHEMA'):
|
||||
try:
|
||||
p_validated = platform.PLATFORM_SCHEMA(p_config)
|
||||
@ -160,7 +178,7 @@ def validate_config(config):
|
||||
return result
|
||||
|
||||
|
||||
REQUIRED = ['esphomeyaml', 'wifi', 'mqtt']
|
||||
REQUIRED = ['esphomeyaml', 'wifi']
|
||||
|
||||
|
||||
def _format_config_error(ex, domain, config):
|
||||
@ -186,13 +204,18 @@ def load_config(path):
|
||||
except OSError:
|
||||
raise ESPHomeYAMLError(u"Could not read configuration file at {}".format(path))
|
||||
|
||||
esp_platform = unicode(config.get(CONF_ESPHOMEYAML, {}).get(CONF_PLATFORM, u""))
|
||||
if CONF_ESPHOMEYAML not in config:
|
||||
raise ESPHomeYAMLError(u"No esphomeyaml section in config")
|
||||
core_conf = config[CONF_ESPHOMEYAML]
|
||||
esp_platform = unicode(core_conf.get(CONF_PLATFORM, u""))
|
||||
esp_platform = esp_platform.upper()
|
||||
if esp_platform not in (ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266):
|
||||
raise ESPHomeYAMLError(u"Invalid ESP Platform {}".format(esp_platform))
|
||||
cv.ESP_PLATFORM = esp_platform
|
||||
cv.BOARD = unicode(config.get(CONF_ESPHOMEYAML, {}).get(CONF_BOARD, u""))
|
||||
helpers.SIMPLIFY = cv.boolean(config.get(CONF_SIMPLIFY, True))
|
||||
if '8266' in esp_platform:
|
||||
esp_platform = ESP_PLATFORM_ESP8266
|
||||
if '32' in esp_platform:
|
||||
esp_platform = ESP_PLATFORM_ESP32
|
||||
core.ESP_PLATFORM = esp_platform
|
||||
core.BOARD = unicode(core_conf.get(CONF_BOARD, u""))
|
||||
core.SIMPLIFY = cv.boolean(core_conf.get(CONF_SIMPLIFY, True))
|
||||
|
||||
try:
|
||||
result = validate_config(config)
|
||||
@ -203,28 +226,6 @@ def load_config(path):
|
||||
return result
|
||||
|
||||
|
||||
def add_platform_task(domain, config):
|
||||
platform_ = config[CONF_PLATFORM]
|
||||
platform = get_platform(domain, platform_)
|
||||
if not hasattr(platform, 'to_code'):
|
||||
raise ESPHomeYAMLError(u"Platform '{}.{}' doesn't have to_code.".format(domain, platform_))
|
||||
add_task(platform.to_code, config)
|
||||
|
||||
|
||||
def add_component_task(domain, config):
|
||||
if domain == CONF_ESPHOMEYAML:
|
||||
add_task(core_to_code, config)
|
||||
return
|
||||
component = get_component(domain)
|
||||
if is_platform_component(component):
|
||||
for conf in config:
|
||||
add_platform_task(domain, conf)
|
||||
else:
|
||||
if not hasattr(component, 'to_code'):
|
||||
raise ESPHomeYAMLError(u"Component '{}' doesn't have to_code.".format(domain))
|
||||
add_task(component.to_code, config)
|
||||
|
||||
|
||||
def line_info(obj, **kwargs):
|
||||
"""Display line config source."""
|
||||
if hasattr(obj, '__config_file__'):
|
||||
|
@ -7,6 +7,7 @@ from datetime import timedelta
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \
|
||||
CONF_NAME, CONF_PAYLOAD_AVAILABLE, \
|
||||
CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \
|
||||
@ -24,9 +25,6 @@ zero_to_one_float = vol.All(vol.Coerce(float), vol.Range(min=0, max=1))
|
||||
positive_int = vol.All(vol.Coerce(int), vol.Range(min=0))
|
||||
positive_not_null_int = vol.All(vol.Coerce(int), vol.Range(min=0, min_included=False))
|
||||
|
||||
ESP_PLATFORM = ''
|
||||
BOARD = ''
|
||||
|
||||
ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
|
||||
|
||||
RESERVED_IDS = [
|
||||
@ -150,7 +148,7 @@ def only_on(platforms):
|
||||
platforms = [platforms]
|
||||
|
||||
def validator_(obj):
|
||||
if ESP_PLATFORM not in platforms:
|
||||
if core.ESP_PLATFORM not in platforms:
|
||||
raise vol.Invalid(u"This feature is only available on {}".format(platforms))
|
||||
return obj
|
||||
|
||||
@ -274,8 +272,8 @@ def ssid(value):
|
||||
raise vol.Invalid("SSID must be a string. Did you wrap it in quotes?")
|
||||
if not value:
|
||||
raise vol.Invalid("SSID can't be empty.")
|
||||
if len(value) > 32:
|
||||
raise vol.Invalid("SSID can't be longer than 32 characters")
|
||||
if len(value) > 31:
|
||||
raise vol.Invalid("SSID can't be longer than 31 characters")
|
||||
return value
|
||||
|
||||
|
||||
@ -300,6 +298,8 @@ def publish_topic(value):
|
||||
value = string_strict(value)
|
||||
if value.endswith('/'):
|
||||
raise vol.Invalid("Publish topic can't end with '/'")
|
||||
if '+' in value or '#' in value:
|
||||
raise vol.Invalid("Publish topic can't contain '+' or '#'")
|
||||
return value
|
||||
|
||||
|
||||
@ -334,23 +334,19 @@ def register_variable_id(value):
|
||||
|
||||
|
||||
class GenerateID(vol.Optional):
|
||||
def __init__(self, basename):
|
||||
def __init__(self, basename, key=CONF_ID):
|
||||
self._basename = basename
|
||||
super(GenerateID, self).__init__(CONF_ID, default=self.default_variable_id)
|
||||
super(GenerateID, self).__init__(key, default=self.default_variable_id)
|
||||
|
||||
def default_variable_id(self):
|
||||
return ensure_unique_string(self._basename, REGISTERED_IDS)
|
||||
|
||||
|
||||
ID_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_ID): invalid,
|
||||
})
|
||||
|
||||
REQUIRED_ID_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_ID): register_variable_id,
|
||||
})
|
||||
|
||||
PLATFORM_SCHEMA = ID_SCHEMA.extend({
|
||||
PLATFORM_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_PLATFORM): valid,
|
||||
})
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
MAJOR_VERSION = 1
|
||||
MINOR_VERSION = 2
|
||||
PATCH_VERSION = '2'
|
||||
PATCH_VERSION = '2-dev'
|
||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||
|
||||
@ -17,6 +17,7 @@ CONF_NAME = 'name'
|
||||
CONF_PLATFORM = 'platform'
|
||||
CONF_BOARD = 'board'
|
||||
CONF_SIMPLIFY = 'simplify'
|
||||
CONF_USE_BUILD_FLAGS = 'use_build_flags'
|
||||
CONF_LIBRARY_URI = 'library_uri'
|
||||
CONF_LOGGER = 'logger'
|
||||
CONF_WIFI = 'wifi'
|
||||
@ -32,6 +33,7 @@ CONF_BROKER = 'broker'
|
||||
CONF_USERNAME = 'username'
|
||||
CONF_POWER_SUPPLY = 'power_supply'
|
||||
CONF_ID = 'id'
|
||||
CONF_MQTT_ID = 'mqtt_id'
|
||||
CONF_PIN = 'pin'
|
||||
CONF_NUMBER = 'number'
|
||||
CONF_INVERTED = 'inverted'
|
||||
@ -151,6 +153,14 @@ CONF_RATE = 'rate'
|
||||
CONF_ADS1115_ID = 'ads1115_id'
|
||||
CONF_MULTIPLEXER = 'multiplexer'
|
||||
CONF_GAIN = 'gain'
|
||||
CONF_SLEEP_DURATION = 'sleep_duration'
|
||||
CONF_WAKEUP_PIN = 'wakeup_pin'
|
||||
CONF_RUN_CYCLES = 'run_cycles'
|
||||
CONF_RUN_DURATION = 'run_duration'
|
||||
CONF_AP = 'ap'
|
||||
CONF_CSS_URL = 'css_url'
|
||||
CONF_JS_URL = 'js_url'
|
||||
CONF_FINGERPRINTS = 'fingerprints'
|
||||
|
||||
ESP32_BOARDS = [
|
||||
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',
|
||||
|
@ -16,3 +16,9 @@ class IPAddress(object):
|
||||
|
||||
def __str__(self):
|
||||
return '.'.join(str(x) for x in self.args)
|
||||
|
||||
|
||||
CONFIG_PATH = None
|
||||
SIMPLIFY = True
|
||||
ESP_PLATFORM = ''
|
||||
BOARD = ''
|
||||
|
@ -4,6 +4,7 @@ import logging
|
||||
import re
|
||||
from collections import OrderedDict, deque
|
||||
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \
|
||||
CONF_INVERTED, \
|
||||
CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_RETAIN, \
|
||||
@ -12,8 +13,6 @@ from esphomeyaml.core import ESPHomeYAMLError, HexInt
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SIMPLIFY = False
|
||||
|
||||
|
||||
def ensure_unique_string(preferred_string, current_strings):
|
||||
test_string = preferred_string
|
||||
@ -45,11 +44,19 @@ def indent(text, padding=u' '):
|
||||
|
||||
class Expression(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
self.requires = []
|
||||
self.required = False
|
||||
|
||||
def __str__(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def require(self):
|
||||
self.required = True
|
||||
for require in self.requires:
|
||||
if require.required:
|
||||
continue
|
||||
require.require()
|
||||
|
||||
|
||||
class RawExpression(Expression):
|
||||
def __init__(self, text):
|
||||
@ -60,15 +67,22 @@ class RawExpression(Expression):
|
||||
return self.text
|
||||
|
||||
|
||||
# pylint: disable=redefined-builtin
|
||||
class AssignmentExpression(Expression):
|
||||
def __init__(self, lhs, rhs, obj):
|
||||
def __init__(self, type, modifier, name, rhs, obj):
|
||||
super(AssignmentExpression, self).__init__()
|
||||
self.obj = obj
|
||||
self.lhs = safe_exp(lhs)
|
||||
self.type = type
|
||||
self.modifier = modifier
|
||||
self.name = name
|
||||
self.rhs = safe_exp(rhs)
|
||||
self.requires.append(self.rhs)
|
||||
self.obj = obj
|
||||
|
||||
def __str__(self):
|
||||
return u"{} = {}".format(self.lhs, self.rhs)
|
||||
type_ = self.type
|
||||
if core.SIMPLIFY:
|
||||
type_ = u'auto'
|
||||
return u"{} {}{} = {}".format(type_, self.modifier, self.name, self.rhs)
|
||||
|
||||
|
||||
class ExpressionList(Expression):
|
||||
@ -78,7 +92,11 @@ class ExpressionList(Expression):
|
||||
args = list(args)
|
||||
while args and args[-1] is None:
|
||||
args.pop()
|
||||
self.args = [safe_exp(x) for x in args]
|
||||
self.args = []
|
||||
for arg in args:
|
||||
exp = safe_exp(arg)
|
||||
self.requires.append(exp)
|
||||
self.args.append(exp)
|
||||
|
||||
def __str__(self):
|
||||
text = u", ".join(unicode(x) for x in self.args)
|
||||
@ -90,6 +108,7 @@ class CallExpression(Expression):
|
||||
super(CallExpression, self).__init__()
|
||||
self.base = base
|
||||
self.args = ExpressionList(*args)
|
||||
self.requires.append(self.args)
|
||||
|
||||
def __str__(self):
|
||||
return u'{}({})'.format(self.base, self.args)
|
||||
@ -103,8 +122,11 @@ class StructInitializer(Expression):
|
||||
args = OrderedDict(args)
|
||||
self.args = OrderedDict()
|
||||
for key, value in args.iteritems():
|
||||
if value is not None:
|
||||
self.args[key] = safe_exp(value)
|
||||
if value is None:
|
||||
continue
|
||||
exp = safe_exp(value)
|
||||
self.args[key] = exp
|
||||
self.requires.append(exp)
|
||||
|
||||
def __str__(self):
|
||||
cpp = u'{}{{\n'.format(self.base)
|
||||
@ -115,17 +137,27 @@ class StructInitializer(Expression):
|
||||
|
||||
|
||||
class ArrayInitializer(Expression):
|
||||
def __init__(self, *args):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ArrayInitializer, self).__init__()
|
||||
self.args = [safe_exp(x) for x in args if x is not None]
|
||||
self.multiline = kwargs.get('multiline', True)
|
||||
self.args = []
|
||||
for arg in args:
|
||||
if arg is None:
|
||||
continue
|
||||
exp = safe_exp(arg)
|
||||
self.args.append(exp)
|
||||
self.requires.append(exp)
|
||||
|
||||
def __str__(self):
|
||||
if not self.args:
|
||||
return u'{}'
|
||||
if self.multiline:
|
||||
cpp = u'{\n'
|
||||
for arg in self.args:
|
||||
cpp += u' {},\n'.format(arg)
|
||||
cpp += u'}'
|
||||
else:
|
||||
cpp = u'{' + u', '.join(str(arg) for arg in self.args) + u'}'
|
||||
return cpp
|
||||
|
||||
|
||||
@ -227,20 +259,22 @@ def statement(expression):
|
||||
|
||||
# pylint: disable=redefined-builtin, invalid-name
|
||||
def variable(type, id, rhs):
|
||||
lhs = RawExpression(u'{} {}'.format(type if not SIMPLIFY else u'auto', id))
|
||||
rhs = safe_exp(rhs)
|
||||
obj = MockObj(id, u'.')
|
||||
add(AssignmentExpression(lhs, rhs, obj))
|
||||
assignment = AssignmentExpression(type, '', id, rhs, obj)
|
||||
add(assignment)
|
||||
_VARIABLES[id] = obj, type
|
||||
obj.requires.append(assignment)
|
||||
return obj
|
||||
|
||||
|
||||
def Pvariable(type, id, rhs):
|
||||
lhs = RawExpression(u'{} *{}'.format(type if not SIMPLIFY else u'auto', id))
|
||||
rhs = safe_exp(rhs)
|
||||
obj = MockObj(id, u'->')
|
||||
add(AssignmentExpression(lhs, rhs, obj))
|
||||
assignment = AssignmentExpression(type, '*', id, rhs, obj)
|
||||
add(assignment)
|
||||
_VARIABLES[id] = obj, type
|
||||
obj.requires.append(assignment)
|
||||
return obj
|
||||
|
||||
|
||||
@ -272,7 +306,6 @@ def get_variable(id, type=None):
|
||||
|
||||
if result is None:
|
||||
raise ESPHomeYAMLError(u"Couldn't find ID '{}' with type {}".format(id, type))
|
||||
result.usages += 1
|
||||
return result
|
||||
|
||||
|
||||
@ -280,17 +313,17 @@ def add_task(func, config):
|
||||
_QUEUE.append((func, config))
|
||||
|
||||
|
||||
def add(expression):
|
||||
def add(expression, require=True):
|
||||
if require and isinstance(expression, Expression):
|
||||
expression.require()
|
||||
_EXPRESSIONS.append(expression)
|
||||
return expression
|
||||
|
||||
|
||||
class MockObj(Expression):
|
||||
def __init__(self, base, op=u'.', parent=None):
|
||||
def __init__(self, base, op=u'.'):
|
||||
self.base = base
|
||||
self.op = op
|
||||
self.usages = 0
|
||||
self.parent = parent
|
||||
super(MockObj, self).__init__()
|
||||
|
||||
def __getattr__(self, attr):
|
||||
@ -299,18 +332,26 @@ class MockObj(Expression):
|
||||
attr = attr[1:]
|
||||
next_op = u'->'
|
||||
op = self.op
|
||||
return MockObj(u'{}{}{}'.format(self.base, op, attr), next_op, self)
|
||||
obj = MockObj(u'{}{}{}'.format(self.base, op, attr), next_op)
|
||||
obj.requires.append(self)
|
||||
return obj
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
self.usages += 1
|
||||
it = self.parent
|
||||
while it is not None:
|
||||
it.usages += 1
|
||||
it = it.parent
|
||||
return CallExpression(self.base, *args)
|
||||
call = CallExpression(self.base, *args)
|
||||
obj = MockObj(call, self.op)
|
||||
obj.requires.append(self)
|
||||
obj.requires.append(call)
|
||||
return obj
|
||||
|
||||
def __str__(self):
|
||||
return self.base
|
||||
return unicode(self.base)
|
||||
|
||||
def require(self):
|
||||
self.required = True
|
||||
for require in self.requires:
|
||||
if require.required:
|
||||
continue
|
||||
require.require()
|
||||
|
||||
|
||||
App = MockObj(u'App')
|
||||
@ -358,13 +399,8 @@ def setup_mqtt_component(obj, config):
|
||||
add(obj.set_custom_command_topic(config[CONF_COMMAND_TOPIC]))
|
||||
if CONF_AVAILABILITY in config:
|
||||
availability = config[CONF_AVAILABILITY]
|
||||
exp = StructInitializer(
|
||||
u'mqtt::Availability',
|
||||
(u'topic', availability[CONF_TOPIC]),
|
||||
(u'payload_available', availability[CONF_PAYLOAD_AVAILABLE]),
|
||||
(u'payload_not_available', availability[CONF_PAYLOAD_NOT_AVAILABLE]),
|
||||
)
|
||||
add(obj.set_availability(exp))
|
||||
add(obj.set_availability(availability[CONF_TOPIC], availability[CONF_PAYLOAD_AVAILABLE],
|
||||
availability[CONF_PAYLOAD_NOT_AVAILABLE]))
|
||||
|
||||
|
||||
def exp_empty_optional(type):
|
||||
|
@ -1,13 +1,17 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from esphomeyaml.const import CONF_BROKER, CONF_DISCOVERY_PREFIX, CONF_ESPHOMEYAML, CONF_LOGGER, \
|
||||
CONF_LOG_TOPIC, CONF_MQTT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TOPIC_PREFIX, \
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.const import CONF_BROKER, CONF_DISCOVERY_PREFIX, CONF_ESPHOMEYAML, \
|
||||
CONF_LOG_TOPIC, \
|
||||
CONF_MQTT, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_TOPIC_PREFIX, \
|
||||
CONF_USERNAME
|
||||
from esphomeyaml.helpers import color
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -38,16 +42,21 @@ def initialize(config, subscriptions, on_message, username, password, client_id)
|
||||
def show_logs(config, topic=None, username=None, password=None, client_id=None):
|
||||
if topic is not None:
|
||||
pass # already have topic
|
||||
elif CONF_LOG_TOPIC in config.get(CONF_LOGGER, {}):
|
||||
topic = config[CONF_LOGGER][CONF_LOG_TOPIC]
|
||||
elif CONF_MQTT in config:
|
||||
conf = config[CONF_MQTT]
|
||||
if CONF_LOG_TOPIC in conf:
|
||||
topic = config[CONF_MQTT][CONF_LOG_TOPIC]
|
||||
elif CONF_TOPIC_PREFIX in config[CONF_MQTT]:
|
||||
topic = config[CONF_MQTT][CONF_TOPIC_PREFIX] + u'/debug'
|
||||
else:
|
||||
topic = config[CONF_ESPHOMEYAML][CONF_NAME] + u'/debug'
|
||||
else:
|
||||
_LOGGER.error(u"MQTT isn't setup, can't start MQTT logs")
|
||||
return 1
|
||||
_LOGGER.info(u"Starting log output from %s", topic)
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
time = datetime.now().time().strftime(u'[%H:%M:%S] ')
|
||||
time = datetime.now().time().strftime(u'[%H:%M:%S]')
|
||||
print(time + msg.payload)
|
||||
|
||||
return initialize(config, [topic], on_message, username, password, client_id)
|
||||
@ -67,3 +76,23 @@ def clear_topic(config, topic, username=None, password=None, client_id=None):
|
||||
client.publish(msg.topic, None, retain=True)
|
||||
|
||||
return initialize(config, [topic], on_message, username, password, client_id)
|
||||
|
||||
|
||||
# From marvinroger/async-mqtt-client -> scripts/get-fingerprint/get-fingerprint.py
|
||||
def get_fingerprint(config):
|
||||
import ssl
|
||||
|
||||
addr = config[CONF_MQTT][CONF_BROKER], config[CONF_MQTT][CONF_PORT]
|
||||
_LOGGER.info("Getting fingerprint from %s:%s", addr[0], addr[1])
|
||||
try:
|
||||
cert_pem = ssl.get_server_certificate(addr)
|
||||
except IOError as err:
|
||||
_LOGGER.error("Unable to connect to server: %s", err)
|
||||
return 1
|
||||
cert_der = ssl.PEM_cert_to_DER_cert(cert_pem)
|
||||
|
||||
sha1 = hashlib.sha1(cert_der).hexdigest()
|
||||
|
||||
print(u"SHA1 Fingerprint: " + color('cyan', sha1))
|
||||
print(u"Copy above string into mqtt.ssl_fingerprints section of {}".format(core.CONFIG_PATH))
|
||||
return 0
|
||||
|
@ -3,6 +3,7 @@ import logging
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.const import ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_NUMBER, CONF_MODE, \
|
||||
CONF_INVERTED
|
||||
|
||||
@ -72,32 +73,32 @@ def _translate_pin(value):
|
||||
pass
|
||||
if value.startswith('GPIO'):
|
||||
return vol.Coerce(int)(value[len('GPIO'):])
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if value in ESP32_PINS:
|
||||
return ESP32_PINS[value]
|
||||
if cv.BOARD not in ESP32_BOARD_TO_PINS:
|
||||
if core.BOARD not in ESP32_BOARD_TO_PINS:
|
||||
raise vol.Invalid(u"ESP32: Unknown board {} with unknown "
|
||||
u"pin {}.".format(cv.BOARD, value))
|
||||
if value not in ESP32_BOARD_TO_PINS[cv.BOARD]:
|
||||
u"pin {}.".format(core.BOARD, value))
|
||||
if value not in ESP32_BOARD_TO_PINS[core.BOARD]:
|
||||
raise vol.Invalid(u"ESP32: Board {} doesn't have"
|
||||
u"pin {}".format(cv.BOARD, value))
|
||||
return ESP32_BOARD_TO_PINS[cv.BOARD][value]
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
u"pin {}".format(core.BOARD, value))
|
||||
return ESP32_BOARD_TO_PINS[core.BOARD][value]
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
if value in ESP8266_PINS:
|
||||
return ESP8266_PINS[value]
|
||||
if cv.BOARD not in ESP8266_BOARD_TO_PINS:
|
||||
if core.BOARD not in ESP8266_BOARD_TO_PINS:
|
||||
raise vol.Invalid(u"ESP8266: Unknown board {} with unknown "
|
||||
u"pin {}.".format(cv.BOARD, value))
|
||||
if value not in ESP8266_BOARD_TO_PINS[cv.BOARD]:
|
||||
u"pin {}.".format(core.BOARD, value))
|
||||
if value not in ESP8266_BOARD_TO_PINS[core.BOARD]:
|
||||
raise vol.Invalid(u"ESP8266: Board {} doesn't have"
|
||||
u"pin {}".format(cv.BOARD, value))
|
||||
return ESP8266_BOARD_TO_PINS[cv.BOARD][value]
|
||||
u"pin {}".format(core.BOARD, value))
|
||||
return ESP8266_BOARD_TO_PINS[core.BOARD][value]
|
||||
raise vol.Invalid(u"Invalid ESP platform.")
|
||||
|
||||
|
||||
def _validate_gpio_pin(value):
|
||||
value = _translate_pin(value)
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if value < 0 or value > 39:
|
||||
raise vol.Invalid(u"ESP32: Invalid pin number: {}".format(value))
|
||||
if 6 <= value <= 11:
|
||||
@ -107,7 +108,7 @@ def _validate_gpio_pin(value):
|
||||
_LOGGER.warning(u"ESP32: Pin %s (20, 24, 28-31) can usually not be used. "
|
||||
u"Be warned.", value)
|
||||
return value
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
if 6 <= value <= 11:
|
||||
_LOGGER.warning(u"ESP8266: Pin %s (6-11) might already be used by the "
|
||||
u"flash interface. Be warned.", value)
|
||||
@ -119,21 +120,21 @@ def _validate_gpio_pin(value):
|
||||
|
||||
def input_pin(value):
|
||||
value = _validate_gpio_pin(value)
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
return value
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
return value
|
||||
raise vol.Invalid(u"Invalid ESP platform.")
|
||||
|
||||
|
||||
def output_pin(value):
|
||||
value = _validate_gpio_pin(value)
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if 34 <= value <= 39:
|
||||
raise vol.Invalid(u"ESP32: Pin {} (34-39) can only be used as "
|
||||
u"input pins.".format(value))
|
||||
return value
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
if value == 16:
|
||||
raise vol.Invalid(u"Pin {} doesn't support output mode".format(value))
|
||||
return value
|
||||
@ -142,11 +143,11 @@ def output_pin(value):
|
||||
|
||||
def analog_pin(value):
|
||||
value = _validate_gpio_pin(value)
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if 32 <= value <= 39: # ADC1
|
||||
return value
|
||||
raise vol.Invalid(u"ESP32: Only pins 32 though 39 support ADC.")
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
if value == 17: # A0
|
||||
return value
|
||||
raise vol.Invalid(u"ESP8266: Only pin A0 (17) supports ADC.")
|
||||
@ -171,9 +172,9 @@ PIN_MODES_ESP32 = [
|
||||
|
||||
def pin_mode(value):
|
||||
value = vol.All(vol.Coerce(str), vol.Upper)(value)
|
||||
if cv.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
return vol.Any(*PIN_MODES_ESP32)(value)
|
||||
elif cv.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
return vol.Any(*PIN_MODES_ESP8266)(value)
|
||||
raise vol.Invalid(u"Invalid ESP platform.")
|
||||
|
||||
@ -195,3 +196,14 @@ GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, vol.Schema({
|
||||
vol.Optional(CONF_MODE): pin_mode,
|
||||
vol.Optional(CONF_INVERTED): cv.boolean,
|
||||
}))
|
||||
|
||||
|
||||
def schema_validate_number(validator):
|
||||
def valid(value):
|
||||
if isinstance(value, dict):
|
||||
value[CONF_NUMBER] = validator(value[CONF_NUMBER])
|
||||
else:
|
||||
value = validator(value)
|
||||
return value
|
||||
|
||||
return valid
|
||||
|
@ -4,9 +4,9 @@ import codecs
|
||||
import errno
|
||||
import os
|
||||
|
||||
from esphomeyaml.config import get_component
|
||||
from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_LOGGER, \
|
||||
CONF_NAME, CONF_PLATFORM, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.config import iter_components
|
||||
from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \
|
||||
CONF_PLATFORM, CONF_USE_BUILD_FLAGS, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
|
||||
CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ==========='
|
||||
@ -52,7 +52,8 @@ framework = arduino
|
||||
lib_deps =
|
||||
{esphomeyaml_uri}
|
||||
${{common.lib_deps}}
|
||||
build_flags ={build_flags}
|
||||
build_flags =
|
||||
{build_flags}
|
||||
${{common.build_flags}}
|
||||
"""
|
||||
|
||||
@ -62,18 +63,41 @@ PLATFORM_TO_PLATFORMIO = {
|
||||
}
|
||||
|
||||
|
||||
def get_build_flags(config, key):
|
||||
build_flags = set()
|
||||
for _, component, conf in iter_components(config):
|
||||
if not hasattr(component, key):
|
||||
continue
|
||||
flags = getattr(component, key)(conf)
|
||||
if flags is None:
|
||||
continue
|
||||
if isinstance(flags, (str, unicode)):
|
||||
flags = [flags]
|
||||
build_flags |= set(flags)
|
||||
return build_flags
|
||||
|
||||
|
||||
def get_ini_content(config):
|
||||
platform = config[CONF_ESPHOMEYAML][CONF_PLATFORM]
|
||||
if platform in PLATFORM_TO_PLATFORMIO:
|
||||
platform = PLATFORM_TO_PLATFORMIO[platform]
|
||||
options = {
|
||||
u'env': config[CONF_ESPHOMEYAML][CONF_NAME],
|
||||
u'platform': PLATFORM_TO_PLATFORMIO[config[CONF_ESPHOMEYAML][CONF_PLATFORM]],
|
||||
u'platform': platform,
|
||||
u'board': config[CONF_ESPHOMEYAML][CONF_BOARD],
|
||||
u'esphomeyaml_uri': config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI],
|
||||
u'build_flags': u'',
|
||||
}
|
||||
if CONF_LOGGER in config:
|
||||
build_flags = get_component(CONF_LOGGER).get_build_flags(config[CONF_LOGGER])
|
||||
build_flags = set()
|
||||
if config[CONF_ESPHOMEYAML][CONF_USE_BUILD_FLAGS]:
|
||||
build_flags |= get_build_flags(config, 'build_flags')
|
||||
build_flags.add(u"-DESPHOMEYAML_USE")
|
||||
build_flags |= get_build_flags(config, 'required_build_flags')
|
||||
|
||||
# avoid changing build flags order
|
||||
build_flags = sorted(list(build_flags))
|
||||
if build_flags:
|
||||
options[u'build_flags'] = u'\n ' + build_flags
|
||||
options[u'build_flags'] = u'\n '.join(build_flags)
|
||||
return INI_CONTENT_FORMAT.format(**options)
|
||||
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import codecs
|
||||
import fnmatch
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
import os
|
||||
from collections import OrderedDict
|
||||
|
||||
import yaml
|
||||
|
||||
@ -79,9 +80,8 @@ def _ordered_dict(loader, node):
|
||||
|
||||
if key in seen:
|
||||
fname = getattr(loader.stream, 'name', '')
|
||||
_LOGGER.error(
|
||||
u'YAML file %s contains duplicate key "%s". '
|
||||
u'Check lines %d and %d.', fname, key, seen[key], line)
|
||||
raise ESPHomeYAMLError(u'YAML file {} contains duplicate key "{}". '
|
||||
u'Check lines {} and {}.'.format(fname, key, seen[key], line))
|
||||
seen[key] = line
|
||||
|
||||
return _add_reference(OrderedDict(nodes), loader, node)
|
||||
|
Loading…
Reference in New Issue
Block a user