Add ESP32 BLE Beacon

This commit is contained in:
Otto Winter 2018-06-12 21:18:04 +02:00
parent 2c30d80490
commit a827b51887
No known key found for this signature in database
GPG key ID: DB66C0BE6013F97E
14 changed files with 274 additions and 42 deletions

View file

@ -9,9 +9,9 @@ from datetime import datetime
from esphomeyaml import const, core, mqtt, wizard, writer, yaml_util from esphomeyaml import const, core, mqtt, wizard, writer, yaml_util
from esphomeyaml.config import core_to_code, get_component, iter_components, read_config from esphomeyaml.config import core_to_code, get_component, iter_components, read_config
from esphomeyaml.const import CONF_BAUD_RATE, CONF_DOMAIN, CONF_ESPHOMEYAML, CONF_HOSTNAME, \ from esphomeyaml.const import CONF_BAUD_RATE, CONF_BUILD_PATH, CONF_DOMAIN, CONF_ESPHOMEYAML, \
CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI, ESP_PLATFORM_ESP8266, \ CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_WIFI, \
CONF_NETWORKS, CONF_BUILD_PATH ESP_PLATFORM_ESP8266
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, _EXPRESSIONS, add, \ from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, _EXPRESSIONS, add, \
add_job, color, flush_tasks, indent, quote, statement add_job, color, flush_tasks, indent, quote, statement
@ -143,9 +143,7 @@ def write_cpp(config):
exp = exp.rhs exp = exp.rhs
all_code.append(unicode(statement(exp))) all_code.append(unicode(statement(exp)))
platformio_ini_s = writer.get_ini_content(config) writer.write_platformio_project(config, get_base_path(config))
ini_path = os.path.join(get_base_path(config), 'platformio.ini')
writer.write_platformio_ini(platformio_ini_s, ini_path)
code_s = indent('\n'.join(line.rstrip() for line in all_code)) code_s = indent('\n'.join(line.rstrip() for line in all_code))
cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp') cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp')
@ -162,9 +160,8 @@ def compile_program(args, config):
def get_upload_host(config): def get_upload_host(config):
has_networks = bool(config[CONF_WIFI].get(CONF_NETWORKS)) if CONF_MANUAL_IP in config[CONF_WIFI]:
if has_networks and CONF_MANUAL_IP in config[CONF_WIFI][CONF_NETWORKS][0]: host = str(config[CONF_WIFI][CONF_MANUAL_IP][CONF_STATIC_IP])
host = str(config[CONF_WIFI][CONF_NETWORKS][0][CONF_MANUAL_IP][CONF_STATIC_IP])
elif CONF_HOSTNAME in config[CONF_WIFI]: elif CONF_HOSTNAME in config[CONF_WIFI]:
host = config[CONF_WIFI][CONF_HOSTNAME] + config[CONF_WIFI][CONF_DOMAIN] host = config[CONF_WIFI][CONF_HOSTNAME] + config[CONF_WIFI][CONF_DOMAIN]
else: else:

View file

@ -2,11 +2,12 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import automation from esphomeyaml import automation
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INVERTED, CONF_MAX_LENGTH, \ from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INTERNAL, CONF_INVERTED, \
CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, CONF_ON_PRESS, \ CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, \
CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_INTERNAL CONF_ON_PRESS, CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_FILTERS, CONF_INVERT, CONF_DELAYED_ON, \
from esphomeyaml.helpers import App, NoArg, Pvariable, add, esphomelib_ns, setup_mqtt_component, \ CONF_DELAYED_OFF, CONF_LAMBDA
add_job from esphomeyaml.helpers import App, NoArg, Pvariable, add, add_job, esphomelib_ns, \
setup_mqtt_component, bool_, process_lambda, ArrayInitializer
DEVICE_CLASSES = [ DEVICE_CLASSES = [
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas', '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
@ -25,13 +26,27 @@ ReleaseTrigger = binary_sensor_ns.ReleaseTrigger
ClickTrigger = binary_sensor_ns.ClickTrigger ClickTrigger = binary_sensor_ns.ClickTrigger
DoubleClickTrigger = binary_sensor_ns.DoubleClickTrigger DoubleClickTrigger = binary_sensor_ns.DoubleClickTrigger
BinarySensor = binary_sensor_ns.BinarySensor BinarySensor = binary_sensor_ns.BinarySensor
InvertFilter = binary_sensor_ns.InvertFilter
LambdaFilter = binary_sensor_ns.LambdaFilter
DelayedOnFilter = binary_sensor_ns.DelayedOnFilter
DelayedOffFilter = binary_sensor_ns.DelayedOffFilter
MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent
FILTER_KEYS = [CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA]
FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
vol.Optional(CONF_INVERT): None,
vol.Optional(CONF_DELAYED_ON): cv.positive_time_period_milliseconds,
vol.Optional(CONF_DELAYED_OFF): cv.positive_time_period_milliseconds,
vol.Optional(CONF_LAMBDA): cv.lambda_,
}, cv.has_exactly_one_key(*FILTER_KEYS))])
BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({ BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTBinarySensorComponent), cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTBinarySensorComponent),
cv.GenerateID(): cv.declare_variable_id(BinarySensor), cv.GenerateID(): cv.declare_variable_id(BinarySensor),
vol.Optional(CONF_INVERTED): cv.boolean,
vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, cv.one_of(*DEVICE_CLASSES)), vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, cv.one_of(*DEVICE_CLASSES)),
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA,
vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PressTrigger), cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PressTrigger),
})]), })]),
@ -49,11 +64,41 @@ BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds, vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
})]), })]),
vol.Optional(CONF_INVERTED): cv.invalid(
"The inverted binary_sensor property has been replaced by the "
"new 'invert' binary sensor filter. Please see "
"https://esphomelib.com/esphomeyaml/components/binary_sensor/index.html."
),
}) })
BINARY_SENSOR_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(BINARY_SENSOR_SCHEMA.schema) BINARY_SENSOR_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(BINARY_SENSOR_SCHEMA.schema)
def setup_filter(config):
if CONF_INVERT in config:
yield InvertFilter.new()
elif CONF_DELAYED_OFF in config:
yield App.register_component(DelayedOffFilter.new(config[CONF_DELAYED_OFF]))
elif CONF_DELAYED_ON in config:
yield App.register_component(DelayedOnFilter.new(config[CONF_DELAYED_ON]))
elif CONF_LAMBDA in config:
lambda_ = None
for lambda_ in process_lambda(config[CONF_LAMBDA], [(bool_, 'x')]):
yield None
yield LambdaFilter.new(lambda_)
def setup_filters(config):
filters = []
for conf in config:
filter = None
for filter in setup_filter(conf):
yield None
filters.append(filter)
yield ArrayInitializer(*filters)
def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config): def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config):
if CONF_INTERNAL in config: if CONF_INTERNAL in config:
add(binary_sensor_var.set_internal(CONF_INTERNAL)) add(binary_sensor_var.set_internal(CONF_INTERNAL))
@ -61,6 +106,11 @@ def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config):
add(binary_sensor_var.set_device_class(config[CONF_DEVICE_CLASS])) add(binary_sensor_var.set_device_class(config[CONF_DEVICE_CLASS]))
if CONF_INVERTED in config: if CONF_INVERTED in config:
add(binary_sensor_var.set_inverted(config[CONF_INVERTED])) add(binary_sensor_var.set_inverted(config[CONF_INVERTED]))
if CONF_FILTERS in config:
filters = None
for filters in setup_filters(config[CONF_FILTERS]):
yield
add(binary_sensor_var.add_filters(filters))
for conf in config.get(CONF_ON_PRESS, []): for conf in config.get(CONF_ON_PRESS, []):
rhs = binary_sensor_var.make_press_trigger() rhs = binary_sensor_var.make_press_trigger()

View file

@ -2,13 +2,13 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor from esphomeyaml.components import binary_sensor
from esphomeyaml.components.esp32_ble import ESP32BLETracker from esphomeyaml.components.esp32_ble_tracker import ESP32BLETracker
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32 from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32
from esphomeyaml.core import HexInt from esphomeyaml.core import HexInt
from esphomeyaml.helpers import ArrayInitializer, get_variable from esphomeyaml.helpers import ArrayInitializer, get_variable
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['esp32_ble'] DEPENDENCIES = ['esp32_ble_tracker']
CONF_ESP32_BLE_ID = 'esp32_ble_id' CONF_ESP32_BLE_ID = 'esp32_ble_id'

View file

@ -0,0 +1,81 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.remote_receiver import RemoteReceiverComponent, remote_ns
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \
CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_RAW, CONF_SONY
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, get_variable
DEPENDENCIES = ['remote_receiver']
IR_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW]
CONF_REMOTE_RECEIVER_ID = 'remote_receiver_id'
CONF_RECEIVER_ID = 'receiver_id'
RemoteReceiver = remote_ns.RemoteReceiver
LGReceiver = remote_ns.LGReceiver
NECReceiver = remote_ns.NECReceiver
PanasonicReceiver = remote_ns.PanasonicReceiver
RawReceiver = remote_ns.RawReceiver
SonyReceiver = remote_ns.SonyReceiver
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_LG): vol.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=28): vol.All(vol.Coerce(int), cv.one_of(28, 32)),
}),
vol.Optional(CONF_NEC): vol.Schema({
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
vol.Required(CONF_COMMAND): cv.hex_uint16_t,
}),
vol.Optional(CONF_SONY): vol.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=12): vol.All(vol.Coerce(int), cv.one_of(12, 15, 20)),
}),
vol.Optional(CONF_PANASONIC): vol.Schema({
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
vol.Required(CONF_COMMAND): cv.hex_uint32_t,
}),
vol.Optional(CONF_RAW): vol.Schema({
vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)),
}),
cv.GenerateID(CONF_REMOTE_RECEIVER_ID): cv.use_variable_id(RemoteReceiverComponent),
cv.GenerateID(CONF_RECEIVER_ID): cv.declare_variable_id(RemoteReceiver),
}), cv.has_exactly_one_key(*IR_KEYS))
def receiver_base(config):
if CONF_LG in config:
conf = config[CONF_LG]
return LGReceiver.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS])
elif CONF_NEC in config:
conf = config[CONF_NEC]
return NECReceiver.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND])
elif CONF_PANASONIC in config:
conf = config[CONF_PANASONIC]
return PanasonicReceiver.new(config[CONF_NAME], conf[CONF_ADDRESS], conf[CONF_COMMAND])
elif CONF_SONY in config:
conf = config[CONF_SONY]
return SonyReceiver.new(config[CONF_NAME], conf[CONF_DATA], conf[CONF_NBITS])
elif CONF_RAW in config:
conf = config[CONF_RAW]
data = ArrayInitializer(*conf[CONF_DATA])
return RawReceiver.new(data, conf[CONF_CARRIER_FREQUENCY])
else:
raise ValueError("Unknown receiver type {}".format(config))
def to_code(config):
remote = None
for remote in get_variable(config[CONF_REMOTE_RECEIVER_ID]):
yield
rhs = App.register_component(receiver_base(config))
receiver = Pvariable(config[CONF_RECEIVER_ID], rhs)
binary_sensor.register_binary_sensor(remote.add_decoder(receiver), config)
BUILD_FLAGS = '-DUSE_REMOTE_RECEIVER'

View file

@ -1,24 +1,5 @@
import voluptuous as vol
from esphomeyaml import config_validation as cv from esphomeyaml import config_validation as cv
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns
ESP_PLATFORMS = [ESP_PLATFORM_ESP32] CONFIG_SCHEMA = cv.invalid("The 'esp32_ble' component has been renamed to the 'esp32_ble_tracker' "
"component in order to avoid confusion with the new 'esp32_ble_beacon' "
ESP32BLETracker = esphomelib_ns.ESP32BLETracker "component.")
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
rhs = App.make_esp32_ble_tracker()
ble = Pvariable(config[CONF_ID], rhs)
if CONF_SCAN_INTERVAL in config:
add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL]))
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'

View file

@ -0,0 +1,35 @@
import voluptuous as vol
from esphomeyaml import config_validation as cv
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32, CONF_UUID, CONF_TYPE
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, RawExpression, ArrayInitializer
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
ESP32BLETracker = esphomelib_ns.ESP32BLETracker
CONF_MAJOR = 'major'
CONF_MINOR = 'minor'
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
vol.Required(CONF_TYPE): vol.All(vol.Upper, cv.one_of('IBEACON')),
vol.Required(CONF_UUID): cv.uuid,
vol.Optional(CONF_MAJOR): cv.uint16_t,
vol.Optional(CONF_MINOR): cv.uint16_t,
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
uuid = config[CONF_UUID].hex
uuid_arr = [RawExpression('0x{}'.format(uuid[i:i+2])) for i in range(0, len(uuid), 2)]
rhs = App.make_esp32_ble_beacon(ArrayInitializer(*uuid_arr, multiline=False))
ble = Pvariable(config[CONF_ID], rhs)
if CONF_MAJOR in config:
add(ble.set_major(config[CONF_MAJOR]))
if CONF_MINOR in config:
add(ble.set_minor(config[CONF_MINOR]))
BUILD_FLAGS = '-DUSE_ESP32_BLE_BEACON'

View file

@ -0,0 +1,24 @@
import voluptuous as vol
from esphomeyaml import config_validation as cv
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
ESP32BLETracker = esphomelib_ns.ESP32BLETracker
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
})
def to_code(config):
rhs = App.make_esp32_ble_tracker()
ble = Pvariable(config[CONF_ID], rhs)
if CONF_SCAN_INTERVAL in config:
add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL]))
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'

View file

@ -8,7 +8,7 @@ from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, C
CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LOG_TOPIC, \ CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LOG_TOPIC, \
CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \ CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \
CONF_SSL_FINGERPRINTS, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \ CONF_SSL_FINGERPRINTS, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \
CONF_WILL_MESSAGE CONF_WILL_MESSAGE, CONF_REBOOT_TIMEOUT
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \ from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \
StructInitializer, \ StructInitializer, \
TemplateArguments, add, esphomelib_ns, optional, std_string TemplateArguments, add, esphomelib_ns, optional, std_string
@ -71,6 +71,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266, vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266,
cv.ensure_list, [validate_fingerprint]), cv.ensure_list, [validate_fingerprint]),
vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds, vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds,
vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds,
vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({ vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger), cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger),
vol.Required(CONF_TOPIC): cv.publish_topic, vol.Required(CONF_TOPIC): cv.publish_topic,
@ -130,6 +131,8 @@ def to_code(config):
add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False))) add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False)))
if CONF_KEEPALIVE in config: if CONF_KEEPALIVE in config:
add(mqtt.set_keep_alive(config[CONF_KEEPALIVE])) add(mqtt.set_keep_alive(config[CONF_KEEPALIVE]))
if CONF_REBOOT_TIMEOUT in config:
add(mqtt.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
for conf in config.get(CONF_ON_MESSAGE, []): for conf in config.get(CONF_ON_MESSAGE, []):
rhs = mqtt.make_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS]) rhs = mqtt.make_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS])

View file

@ -0,0 +1,23 @@
import voluptuous as vol
from esphomeyaml import config_validation as cv, pins
from esphomeyaml.const import CONF_ID, CONF_PIN
from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_output_pin_expression
StatusLED = esphomelib_ns.StatusLED
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(StatusLED),
vol.Optional(CONF_PIN): pins.gpio_output_pin_schema,
})
def to_code(config):
pin = None
for pin in gpio_output_pin_expression(config[CONF_PIN]):
yield
rhs = App.make_status_led(pin)
Pvariable(config[CONF_ID], rhs)
BUILD_FLAGS = '-DUSE_STATUS_LED'

View file

@ -3,8 +3,8 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv import esphomeyaml.config_validation as cv
from esphomeyaml import core from esphomeyaml import core
from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \ from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \
CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_NETWORKS, CONF_PASSWORD, CONF_SSID, \ CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_REBOOT_TIMEOUT, \
CONF_STATIC_IP, CONF_SUBNET, ESP_PLATFORM_ESP8266 CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, ESP_PLATFORM_ESP8266
from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, esphomelib_ns, global_ns from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, esphomelib_ns, global_ns
@ -78,6 +78,7 @@ CONFIG_SCHEMA = vol.All(vol.Schema({
vol.Optional(CONF_AP): WIFI_NETWORK_AP, vol.Optional(CONF_AP): WIFI_NETWORK_AP,
vol.Optional(CONF_HOSTNAME): cv.hostname, vol.Optional(CONF_HOSTNAME): cv.hostname,
vol.Optional(CONF_DOMAIN, default='.local'): cv.domainname, vol.Optional(CONF_DOMAIN, default='.local'): cv.domainname,
vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds,
}), validate) }), validate)
@ -123,6 +124,9 @@ def to_code(config):
if CONF_HOSTNAME in config: if CONF_HOSTNAME in config:
add(wifi.set_hostname(config[CONF_HOSTNAME])) add(wifi.set_hostname(config[CONF_HOSTNAME]))
if CONF_REBOOT_TIMEOUT in config:
add(wifi.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
def lib_deps(config): def lib_deps(config):
if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:

View file

@ -4,6 +4,7 @@ from __future__ import print_function
import logging import logging
import re import re
import uuid as uuid_
import voluptuous as vol import voluptuous as vol
@ -348,6 +349,10 @@ def mac_address(value):
return core.MACAddress(*parts_int) return core.MACAddress(*parts_int)
def uuid(value):
return vol.Coerce(uuid_.UUID)(value)
METRIC_SUFFIXES = { METRIC_SUFFIXES = {
'E': 1e18, 'P': 1e15, 'T': 1e12, 'G': 1e9, 'M': 1e6, 'k': 1e3, 'da': 10, 'd': 1e-1, 'E': 1e18, 'P': 1e15, 'T': 1e12, 'G': 1e9, 'M': 1e6, 'k': 1e3, 'da': 10, 'd': 1e-1,
'c': 1e-2, 'm': 0.001, u'µ': 1e-6, 'u': 1e-6, 'n': 1e-9, 'p': 1e-12, 'f': 1e-15, 'a': 1e-18, 'c': 1e-2, 'm': 0.001, u'µ': 1e-6, 'u': 1e-6, 'n': 1e-9, 'p': 1e-12, 'f': 1e-15, 'a': 1e-18,

View file

@ -241,6 +241,12 @@ CONF_IDLE = 'idle'
CONF_NETWORKS = 'networks' CONF_NETWORKS = 'networks'
CONF_INTERNAL = 'internal' CONF_INTERNAL = 'internal'
CONF_BUILD_PATH = 'build_path' CONF_BUILD_PATH = 'build_path'
CONF_REBOOT_TIMEOUT = 'reboot_timeout'
CONF_INVERT = 'invert'
CONF_DELAYED_ON = 'delayed_on'
CONF_DELAYED_OFF = 'delayed_off'
CONF_UUID = 'uuid'
CONF_TYPE = 'type'
ESP32_BOARDS = [ ESP32_BOARDS = [
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1', 'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',

View file

@ -176,6 +176,23 @@ def write_platformio_ini(content, path):
f_handle.write(full_file) f_handle.write(full_file)
def write_platformio_project(config, path):
platformio_ini = os.path.join(path, 'platformio.ini')
content = get_ini_content(config)
if 'esp32_ble_beacon' in config:
content += 'board_build.partitions = partitions.csv\n'
partitions_csv = os.path.join(path, 'partitions.csv')
if not os.path.isfile(partitions_csv):
with open(partitions_csv, "w") as f:
f.write("nvs, data, nvs, 0x009000, 0x005000,\n")
f.write("otadata, data, ota, 0x00e000, 0x002000,\n")
f.write("app0, app, ota_0, 0x010000, 0x190000,\n")
f.write("app1, app, ota_1, 0x200000, 0x190000,\n")
f.write("eeprom, data, 0x99, 0x390000, 0x001000,\n")
f.write("spiffs, data, spiffs, 0x391000, 0x00F000\n")
write_platformio_ini(content, platformio_ini)
def write_cpp(code_s, path): def write_cpp(code_s, path):
if os.path.isfile(path): if os.path.isfile(path):
try: try:

View file

@ -4,6 +4,7 @@ import codecs
import fnmatch import fnmatch
import logging import logging
import os import os
import uuid
from collections import OrderedDict from collections import OrderedDict
import yaml import yaml
@ -285,6 +286,10 @@ def represent_id(_, data):
return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=data.id) return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=data.id)
def represent_uuid(_, data):
return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=str(data))
yaml.SafeDumper.add_representer( yaml.SafeDumper.add_representer(
OrderedDict, OrderedDict,
lambda dumper, value: lambda dumper, value:
@ -304,3 +309,4 @@ yaml.SafeDumper.add_representer(MACAddress, stringify_representer)
yaml.SafeDumper.add_multi_representer(TimePeriod, represent_time_period) yaml.SafeDumper.add_multi_representer(TimePeriod, represent_time_period)
yaml.SafeDumper.add_multi_representer(Lambda, represent_lambda) yaml.SafeDumper.add_multi_representer(Lambda, represent_lambda)
yaml.SafeDumper.add_multi_representer(core.ID, represent_id) yaml.SafeDumper.add_multi_representer(core.ID, represent_id)
yaml.SafeDumper.add_multi_representer(uuid.UUID, represent_uuid)