1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-05 21:02:20 +01:00

Add ESP32 BLE Beacon

This commit is contained in:
Otto Winter
2018-06-12 21:18:04 +02:00
parent 2c30d80490
commit a827b51887
14 changed files with 274 additions and 42 deletions

View File

@@ -2,11 +2,12 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import automation
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INVERTED, CONF_MAX_LENGTH, \
CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, CONF_ON_PRESS, \
CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_INTERNAL
from esphomeyaml.helpers import App, NoArg, Pvariable, add, esphomelib_ns, setup_mqtt_component, \
add_job
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INTERNAL, CONF_INVERTED, \
CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, \
CONF_ON_PRESS, CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_FILTERS, CONF_INVERT, CONF_DELAYED_ON, \
CONF_DELAYED_OFF, CONF_LAMBDA
from esphomeyaml.helpers import App, NoArg, Pvariable, add, add_job, esphomelib_ns, \
setup_mqtt_component, bool_, process_lambda, ArrayInitializer
DEVICE_CLASSES = [
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
@@ -25,13 +26,27 @@ ReleaseTrigger = binary_sensor_ns.ReleaseTrigger
ClickTrigger = binary_sensor_ns.ClickTrigger
DoubleClickTrigger = binary_sensor_ns.DoubleClickTrigger
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
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({
cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTBinarySensorComponent),
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_FILTERS): FILTERS_SCHEMA,
vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
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_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)
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):
if CONF_INTERNAL in config:
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]))
if CONF_INVERTED in config:
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, []):
rhs = binary_sensor_var.make_press_trigger()

View File

@@ -2,13 +2,13 @@ import voluptuous as vol
import esphomeyaml.config_validation as cv
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.core import HexInt
from esphomeyaml.helpers import ArrayInitializer, get_variable
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['esp32_ble']
DEPENDENCIES = ['esp32_ble_tracker']
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'