1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-15 15:18:16 +00:00

Preparations for 1.3

This commit is contained in:
Otto Winter 2018-04-18 10:30:46 +02:00
parent be247763b6
commit 971d121398
No known key found for this signature in database
GPG Key ID: DB66C0BE6013F97E
12 changed files with 167 additions and 70 deletions

View File

@ -1,9 +1,9 @@
import voluptuous as vol
from esphomeyaml import config_validation as cv, pins
from esphomeyaml.const import CONF_SLEEP_DURATION, CONF_WAKEUP_PIN, CONF_RUN_CYCLES, \
CONF_RUN_DURATION, CONF_ID, CONF_NUMBER
from esphomeyaml.helpers import App, add, Pvariable, exp_gpio_input_pin
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
DEPENDENCIES = ['logger']
@ -11,9 +11,8 @@ DEPENDENCIES = ['logger']
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".format(
', '.join(str(x) for x in valid_pins))
)
raise vol.Invalid(u"Only pins {} support wakeup"
u"".format(', '.join(str(x) for x in valid_pins)))
return value

View File

@ -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, CONF_LOG_TOPIC
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_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
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,6 +30,13 @@ def validate_broker(value):
return value
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,
@ -41,6 +51,8 @@ CONFIG_SCHEMA = vol.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_FINGERPRINTS): vol.All(cv.only_on_esp8266,
cv.ensure_list, [validate_fingerprint]),
})
@ -77,3 +89,13 @@ def to_code(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_FINGERPRINTS in config:
for fingerprint in config[CONF_FINGERPRINTS]:
arr = [fingerprint[i:i + 2] for i in range(0, 40, 2)]
add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr)))
def build_flags(config):
if CONF_FINGERPRINTS in config:
return '-DASYNC_TCP_SSL_ENABLED'
return None

View File

@ -2,10 +2,9 @@ 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]

View File

@ -3,19 +3,26 @@ import logging
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_PORT
from esphomeyaml.helpers import App, add
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):
add(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)
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):

View File

@ -2,24 +2,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
CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, CONF_WIFI, CONF_AP, \
CONF_CHANNEL
from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add
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(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({
vol.Required(CONF_STATIC_IP): cv.ipv4,
vol.Required(CONF_GATEWAY): cv.ipv4,
vol.Required(CONF_SUBNET): cv.ipv4,
vol.Inclusive(CONF_DNS1, 'dns'): cv.ipv4,
vol.Inclusive(CONF_DNS2, 'dns'): cv.ipv4,
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 +53,38 @@ def safe_ip(ip):
return IPAddress(*ip.args)
def manual_ip(config):
return StructInitializer(
'ManualIP',
('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))),
)
def to_code(config):
rhs = App.init_wifi(config[CONF_SSID], config.get(CONF_PASSWORD))
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 CONF_MANUAL_IP in config:
manual_ip = config[CONF_MANUAL_IP]
exp = 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))),
)
add(wifi.set_manual_ip(exp))
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]))

View File

@ -9,10 +9,9 @@ from voluptuous.humanize import humanize_error
import esphomeyaml.config_validation as cv
from esphomeyaml import core, 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, CONF_USE_BUILD_FLAGS
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, color
@ -22,8 +21,7 @@ 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,
@ -31,7 +29,7 @@ CORE_SCHEMA = vol.Schema({
})
REQUIRED_COMPONENTS = [
CONF_ESPHOMEYAML, CONF_WIFI, CONF_MQTT
CONF_ESPHOMEYAML, CONF_WIFI
]
_COMPONENT_CACHE = {}
@ -159,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)
@ -201,8 +209,10 @@ def load_config(path):
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))
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))

View File

@ -272,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

View File

@ -157,6 +157,10 @@ 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',

View File

@ -67,6 +67,7 @@ class RawExpression(Expression):
return self.text
# pylint: disable=redefined-builtin
class AssignmentExpression(Expression):
def __init__(self, type, modifier, name, rhs, obj):
super(AssignmentExpression, self).__init__()
@ -136,23 +137,27 @@ class StructInitializer(Expression):
class ArrayInitializer(Expression):
def __init__(self, *args):
def __init__(self, *args, **kwargs):
super(ArrayInitializer, self).__init__()
self.multiline = kwargs.get('multiline', True)
self.args = []
for x in args:
if x is None:
for arg in args:
if arg is None:
continue
exp = safe_exp(x)
exp = safe_exp(arg)
self.args.append(exp)
self.requires.append(exp)
def __str__(self):
if not self.args:
return u'{}'
cpp = u'{\n'
for arg in self.args:
cpp += u' {},\n'.format(arg)
cpp += 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

View File

@ -7,8 +7,9 @@ from datetime import datetime
import paho.mqtt.client as mqtt
from esphomeyaml import core
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.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
@ -41,12 +42,17 @@ 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_MQTT, {}):
topic = config[CONF_MQTT][CONF_LOG_TOPIC]
elif CONF_TOPIC_PREFIX in config[CONF_MQTT]:
topic = config[CONF_MQTT][CONF_TOPIC_PREFIX] + u'/debug'
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:
topic = config[CONF_ESPHOMEYAML][CONF_NAME] + u'/debug'
_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):

View File

@ -206,4 +206,4 @@ def schema_validate_number(validator):
value = validator(value)
return value
return valid
return valid

View File

@ -6,7 +6,7 @@ import os
from esphomeyaml.config import iter_components
from esphomeyaml.const import CONF_BOARD, CONF_ESPHOMEYAML, CONF_LIBRARY_URI, CONF_NAME, \
CONF_PLATFORM, ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_USE_BUILD_FLAGS
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 ==========='
@ -64,9 +64,12 @@ PLATFORM_TO_PLATFORMIO = {
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'',
@ -74,7 +77,7 @@ def get_ini_content(config):
if config[CONF_ESPHOMEYAML][CONF_USE_BUILD_FLAGS]:
build_flags = set()
build_flags.add(u"-DESPHOMEYAML_USE")
for domain, component, conf in iter_components(config):
for _, component, conf in iter_components(config):
if not hasattr(component, u'build_flags'):
continue
flags = component.build_flags(conf)