mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 22:48:10 +01:00
Preparations for 1.5.0
This commit is contained in:
parent
eec163644d
commit
262855ff62
49 changed files with 1082 additions and 221 deletions
|
@ -13,10 +13,6 @@ COPY docker/platformio.ini /usr/src/app/
|
||||||
RUN platformio settings set enable_telemetry No && \
|
RUN platformio settings set enable_telemetry No && \
|
||||||
platformio run -e espressif32 -e espressif8266; exit 0
|
platformio run -e espressif32 -e espressif8266; exit 0
|
||||||
|
|
||||||
# Fix issue with static IP on ESP32: https://github.com/espressif/arduino-esp32/issues/1081
|
|
||||||
RUN curl https://github.com/espressif/arduino-esp32/commit/144480637a718844b8f48f4392da8d4f622f2e5e.patch | \
|
|
||||||
patch /root/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.cpp
|
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN pip install -e .
|
RUN pip install -e .
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,10 @@ def upload_program(config, args, port):
|
||||||
return run_platformio('platformio', 'run', '-d', get_base_path(config),
|
return run_platformio('platformio', 'run', '-d', get_base_path(config),
|
||||||
'-t', 'upload', '--upload-port', port)
|
'-t', 'upload', '--upload-port', port)
|
||||||
|
|
||||||
|
if 'ota' not in config:
|
||||||
|
_LOGGER.error("No serial port found and OTA not enabled. Can't upload!")
|
||||||
|
return -1
|
||||||
|
|
||||||
if CONF_MANUAL_IP in config[CONF_WIFI]:
|
if CONF_MANUAL_IP in config[CONF_WIFI]:
|
||||||
host = str(config[CONF_WIFI][CONF_MANUAL_IP][CONF_STATIC_IP])
|
host = str(config[CONF_WIFI][CONF_MANUAL_IP][CONF_STATIC_IP])
|
||||||
elif CONF_HOSTNAME in config[CONF_WIFI]:
|
elif CONF_HOSTNAME in config[CONF_WIFI]:
|
||||||
|
|
|
@ -2,27 +2,19 @@ import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_RATE
|
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_RATE
|
||||||
from esphomeyaml.helpers import App, Pvariable, RawExpression, add, HexIntLiteral
|
from esphomeyaml.helpers import App, Pvariable
|
||||||
|
|
||||||
DEPENDENCIES = ['i2c']
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
ADS1115_COMPONENT_CLASS = 'sensor::ADS1115Component'
|
ADS1115_COMPONENT_CLASS = 'sensor::ADS1115Component'
|
||||||
|
|
||||||
RATES = {
|
RATE_REMOVE_MESSAGE = """The rate option has been removed in 1.5.0 and is no longer required."""
|
||||||
8: 'ADS1115_RATE_8',
|
|
||||||
16: 'ADS1115_RATE_16',
|
|
||||||
32: 'ADS1115_RATE_32',
|
|
||||||
64: 'ADS1115_RATE_64',
|
|
||||||
128: 'ADS1115_RATE_128',
|
|
||||||
250: 'ADS1115_RATE_250',
|
|
||||||
475: 'ADS1115_RATE_475',
|
|
||||||
860: 'ADS1115_RATE_860',
|
|
||||||
}
|
|
||||||
|
|
||||||
ADS1115_SCHEMA = vol.Schema({
|
ADS1115_SCHEMA = vol.Schema({
|
||||||
cv.GenerateID('ads1115'): cv.register_variable_id,
|
cv.GenerateID('ads1115'): cv.register_variable_id,
|
||||||
vol.Required(CONF_ADDRESS): cv.i2c_address,
|
vol.Required(CONF_ADDRESS): cv.i2c_address,
|
||||||
vol.Optional(CONF_RATE): vol.All(vol.Coerce(int), vol.Any(*list(RATES.keys()))),
|
|
||||||
|
vol.Optional(CONF_RATE): cv.invalid(RATE_REMOVE_MESSAGE)
|
||||||
})
|
})
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
|
CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
|
||||||
|
@ -30,11 +22,8 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
|
||||||
|
|
||||||
def to_code(config):
|
def to_code(config):
|
||||||
for conf in config:
|
for conf in config:
|
||||||
address = HexIntLiteral(conf[CONF_ADDRESS])
|
rhs = App.make_ads1115_component(conf[CONF_ADDRESS])
|
||||||
rhs = App.make_ads1115_component(address)
|
Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
||||||
ads1115 = Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
|
||||||
if CONF_RATE in conf:
|
|
||||||
add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]])))
|
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
|
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED
|
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED, CONF_MQTT_ID
|
||||||
from esphomeyaml.helpers import add, setup_mqtt_component
|
from esphomeyaml.helpers import add, setup_mqtt_component, App, Pvariable
|
||||||
|
|
||||||
DEVICE_CLASSES = [
|
DEVICE_CLASSES = [
|
||||||
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
|
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
|
||||||
|
@ -23,6 +23,10 @@ MQTT_BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
MQTT_BINARY_SENSOR_ID_SCHEMA = MQTT_BINARY_SENSOR_SCHEMA.extend({
|
||||||
|
cv.GenerateID('mqtt_binary_sensor', CONF_MQTT_ID): cv.register_variable_id,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup_binary_sensor(obj, config):
|
def setup_binary_sensor(obj, config):
|
||||||
if CONF_DEVICE_CLASS in config:
|
if CONF_DEVICE_CLASS in config:
|
||||||
|
@ -35,4 +39,11 @@ def setup_mqtt_binary_sensor(obj, config):
|
||||||
setup_mqtt_component(obj, config)
|
setup_mqtt_component(obj, config)
|
||||||
|
|
||||||
|
|
||||||
|
def register_binary_sensor(var, config):
|
||||||
|
setup_binary_sensor(var, config)
|
||||||
|
rhs = App.register_binary_sensor(var)
|
||||||
|
mqtt_sensor = Pvariable('binary_sensor::MQTTBinarySensorComponent', config[CONF_MQTT_ID], rhs)
|
||||||
|
setup_mqtt_binary_sensor(mqtt_sensor, config)
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_BINARY_SENSOR'
|
BUILD_FLAGS = '-DUSE_BINARY_SENSOR'
|
||||||
|
|
44
esphomeyaml/components/binary_sensor/esp32_ble.py
Normal file
44
esphomeyaml/components/binary_sensor/esp32_ble.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml.components import binary_sensor
|
||||||
|
from esphomeyaml.const import CONF_ID, CONF_MAC_ADDRESS, CONF_NAME, ESP_PLATFORM_ESP32
|
||||||
|
from esphomeyaml.core import HexInt, MACAddress
|
||||||
|
from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable
|
||||||
|
|
||||||
|
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||||
|
DEPENDENCIES = ['esp32_ble']
|
||||||
|
|
||||||
|
|
||||||
|
def validate_mac(value):
|
||||||
|
value = cv.string_strict(value)
|
||||||
|
parts = value.split(':')
|
||||||
|
if len(parts) != 6:
|
||||||
|
raise vol.Invalid("MAC Address must consist of 6 : (colon) separated parts")
|
||||||
|
parts_int = []
|
||||||
|
if any(len(part) != 2 for part in parts):
|
||||||
|
raise vol.Invalid("MAC Address must be format XX:XX:XX:XX:XX:XX")
|
||||||
|
for part in parts:
|
||||||
|
try:
|
||||||
|
parts_int.append(int(part, 16))
|
||||||
|
except ValueError:
|
||||||
|
raise vol.Invalid("MAC Address parts must be hexadecimal values from 00 to FF")
|
||||||
|
|
||||||
|
return MACAddress(*parts_int)
|
||||||
|
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('esp32_ble_device'): cv.register_variable_id,
|
||||||
|
vol.Required(CONF_MAC_ADDRESS): validate_mac,
|
||||||
|
}).extend(binary_sensor.MQTT_BINARY_SENSOR_ID_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
hub = get_variable(None, type='ESP32BLETracker')
|
||||||
|
addr = [HexInt(i) for i in config[CONF_MAC_ADDRESS].parts]
|
||||||
|
rhs = hub.make_device(config[CONF_NAME], ArrayInitializer(*addr, multiline=False))
|
||||||
|
device = Pvariable('ESP32BLEDevice', config[CONF_ID], rhs)
|
||||||
|
binary_sensor.register_binary_sensor(device, config)
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'
|
49
esphomeyaml/components/binary_sensor/esp32_touch.py
Normal file
49
esphomeyaml/components/binary_sensor/esp32_touch.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml.components import binary_sensor
|
||||||
|
from esphomeyaml.const import CONF_ID, CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32
|
||||||
|
from esphomeyaml.helpers import Pvariable, RawExpression, get_variable
|
||||||
|
from esphomeyaml.pins import validate_gpio_pin
|
||||||
|
|
||||||
|
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||||
|
|
||||||
|
DEPENDENCIES = ['esp32_touch']
|
||||||
|
|
||||||
|
TOUCH_PADS = {
|
||||||
|
4: 'TOUCH_PAD_NUM0',
|
||||||
|
0: 'TOUCH_PAD_NUM1',
|
||||||
|
2: 'TOUCH_PAD_NUM2',
|
||||||
|
15: 'TOUCH_PAD_NUM3',
|
||||||
|
13: 'TOUCH_PAD_NUM4',
|
||||||
|
12: 'TOUCH_PAD_NUM5',
|
||||||
|
14: 'TOUCH_PAD_NUM6',
|
||||||
|
27: 'TOUCH_PAD_NUM7',
|
||||||
|
33: 'TOUCH_PAD_NUM8',
|
||||||
|
32: 'TOUCH_PAD_NUM9',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_touch_pad(value):
|
||||||
|
value = validate_gpio_pin(value)
|
||||||
|
if value not in TOUCH_PADS:
|
||||||
|
raise vol.Invalid("Pin {} does not support touch pads.".format(value))
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('esp32_touch_pad'): cv.register_variable_id,
|
||||||
|
vol.Required(CONF_PIN): validate_touch_pad,
|
||||||
|
vol.Required(CONF_THRESHOLD): cv.uint16_t,
|
||||||
|
}).extend(binary_sensor.MQTT_BINARY_SENSOR_ID_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
hub = get_variable(None, type='ESP32TouchComponent')
|
||||||
|
touch_pad = RawExpression(TOUCH_PADS[config[CONF_PIN]])
|
||||||
|
rhs = hub.make_touch_pad(config[CONF_NAME], touch_pad, config[CONF_THRESHOLD])
|
||||||
|
device = Pvariable('ESP32TouchBinarySensor', config[CONF_ID], rhs)
|
||||||
|
binary_sensor.register_binary_sensor(device, config)
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR'
|
|
@ -10,7 +10,7 @@ DALLAS_COMPONENT_CLASS = 'sensor::DallasComponent'
|
||||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||||
cv.GenerateID('dallas'): cv.register_variable_id,
|
cv.GenerateID('dallas'): cv.register_variable_id,
|
||||||
vol.Required(CONF_PIN): pins.input_output_pin,
|
vol.Required(CONF_PIN): pins.input_output_pin,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
})])
|
})])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ def validate_pin_number(value):
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema({
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
cv.GenerateID('deep_sleep'): cv.register_variable_id,
|
cv.GenerateID('deep_sleep'): cv.register_variable_id,
|
||||||
vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period,
|
vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
|
||||||
vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.GPIO_INPUT_PIN_SCHEMA,
|
vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.GPIO_INPUT_PIN_SCHEMA,
|
||||||
pins.schema_validate_number(validate_pin_number)),
|
pins.schema_validate_number(validate_pin_number)),
|
||||||
vol.Optional(CONF_RUN_CYCLES): cv.positive_int,
|
vol.Optional(CONF_RUN_CYCLES): cv.positive_int,
|
||||||
vol.Optional(CONF_RUN_DURATION): cv.positive_time_period,
|
vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
22
esphomeyaml/components/esp32_ble.py
Normal file
22
esphomeyaml/components/esp32_ble.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
|
cv.GenerateID('esp32_ble'): cv.register_variable_id,
|
||||||
|
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_esp32_ble_tracker()
|
||||||
|
ble = Pvariable('ESP32BLETracker', 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'
|
83
esphomeyaml/components/esp32_touch.py
Normal file
83
esphomeyaml/components/esp32_touch.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from esphomeyaml import config_validation as cv
|
||||||
|
from esphomeyaml.const import CONF_ID, CONF_SETUP_MODE, CONF_IIR_FILTER, \
|
||||||
|
CONF_SLEEP_DURATION, CONF_MEASUREMENT_DURATION, CONF_LOW_VOLTAGE_REFERENCE, \
|
||||||
|
CONF_HIGH_VOLTAGE_REFERENCE, CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32
|
||||||
|
from esphomeyaml.core import TimePeriod
|
||||||
|
from esphomeyaml.helpers import App, Pvariable, add
|
||||||
|
|
||||||
|
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||||
|
|
||||||
|
|
||||||
|
def validate_voltage(values):
|
||||||
|
def validator(value):
|
||||||
|
if isinstance(value, float) and value.is_integer():
|
||||||
|
value = int(value)
|
||||||
|
value = cv.string(value)
|
||||||
|
if not value.endswith('V'):
|
||||||
|
value += 'V'
|
||||||
|
if value not in values:
|
||||||
|
raise vol.Invalid('Must be one of {}'.format(values))
|
||||||
|
return value
|
||||||
|
return validator
|
||||||
|
|
||||||
|
|
||||||
|
LOW_VOLTAGE_REFERENCE = {
|
||||||
|
'0.5V': 'TOUCH_LVOLT_0V5',
|
||||||
|
'0.6V': 'TOUCH_LVOLT_0V6',
|
||||||
|
'0.7V': 'TOUCH_LVOLT_0V7',
|
||||||
|
'0.8V': 'TOUCH_LVOLT_0V8',
|
||||||
|
}
|
||||||
|
HIGH_VOLTAGE_REFERENCE = {
|
||||||
|
'2.4V': 'TOUCH_HVOLT_2V4',
|
||||||
|
'2.5V': 'TOUCH_HVOLT_2V5',
|
||||||
|
'2.6V': 'TOUCH_HVOLT_2V6',
|
||||||
|
'2.7V': 'TOUCH_HVOLT_2V7',
|
||||||
|
}
|
||||||
|
VOLTAGE_ATTENUATION = {
|
||||||
|
'1.5V': 'TOUCH_HVOLT_ATTEN_1V5',
|
||||||
|
'1V': 'TOUCH_HVOLT_ATTEN_1V',
|
||||||
|
'0.5V': 'TOUCH_HVOLT_ATTEN_0V5',
|
||||||
|
'0V': 'TOUCH_HVOLT_ATTEN_0V',
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
|
cv.GenerateID('esp32_ble'): cv.register_variable_id,
|
||||||
|
vol.Optional(CONF_SETUP_MODE): cv.boolean,
|
||||||
|
vol.Optional(CONF_IIR_FILTER): cv.positive_time_period_milliseconds,
|
||||||
|
vol.Optional(CONF_SLEEP_DURATION):
|
||||||
|
vol.All(cv.positive_time_period, vol.Range(max=TimePeriod(microseconds=436900))),
|
||||||
|
vol.Optional(CONF_MEASUREMENT_DURATION):
|
||||||
|
vol.All(cv.positive_time_period, vol.Range(max=TimePeriod(microseconds=8192))),
|
||||||
|
vol.Optional(CONF_LOW_VOLTAGE_REFERENCE): validate_voltage(LOW_VOLTAGE_REFERENCE),
|
||||||
|
vol.Optional(CONF_HIGH_VOLTAGE_REFERENCE): validate_voltage(HIGH_VOLTAGE_REFERENCE),
|
||||||
|
vol.Optional(CONF_VOLTAGE_ATTENUATION): validate_voltage(VOLTAGE_ATTENUATION),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_esp32_touch_component()
|
||||||
|
touch = Pvariable('binary_sensor::ESP32TouchComponent', config[CONF_ID], rhs)
|
||||||
|
if CONF_SETUP_MODE in config:
|
||||||
|
add(touch.set_setup_mode(config[CONF_SETUP_MODE]))
|
||||||
|
if CONF_IIR_FILTER in config:
|
||||||
|
add(touch.set_iir_filter(config[CONF_IIR_FILTER]))
|
||||||
|
if CONF_SLEEP_DURATION in config:
|
||||||
|
sleep_duration = int(config[CONF_SLEEP_DURATION].total_microseconds * 6.6667)
|
||||||
|
add(touch.set_sleep_duration(sleep_duration))
|
||||||
|
if CONF_MEASUREMENT_DURATION in config:
|
||||||
|
measurement_duration = int(config[CONF_MEASUREMENT_DURATION].total_microseconds * 0.125)
|
||||||
|
add(touch.set_measurement_duration(measurement_duration))
|
||||||
|
if CONF_LOW_VOLTAGE_REFERENCE in config:
|
||||||
|
value = LOW_VOLTAGE_REFERENCE[config[CONF_LOW_VOLTAGE_REFERENCE]]
|
||||||
|
add(touch.set_low_voltage_reference(value))
|
||||||
|
if CONF_HIGH_VOLTAGE_REFERENCE in config:
|
||||||
|
value = HIGH_VOLTAGE_REFERENCE[config[CONF_HIGH_VOLTAGE_REFERENCE]]
|
||||||
|
add(touch.set_high_voltage_reference(value))
|
||||||
|
if CONF_VOLTAGE_ATTENUATION in config:
|
||||||
|
value = VOLTAGE_ATTENUATION[config[CONF_VOLTAGE_ATTENUATION]]
|
||||||
|
add(touch.set_voltage_attenuation(value))
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR'
|
|
@ -2,14 +2,16 @@ import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml import pins
|
from esphomeyaml import pins
|
||||||
from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID
|
from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID, \
|
||||||
|
CONF_RECEIVE_TIMEOUT
|
||||||
from esphomeyaml.helpers import App, add, Pvariable
|
from esphomeyaml.helpers import App, add, Pvariable
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema({
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
cv.GenerateID('i2c'): cv.register_variable_id,
|
cv.GenerateID('i2c'): cv.register_variable_id,
|
||||||
vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin,
|
vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin,
|
||||||
vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin,
|
vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin,
|
||||||
vol.Optional(CONF_FREQUENCY): vol.All(cv.only_on_esp32, cv.positive_int),
|
vol.Optional(CONF_FREQUENCY): cv.positive_int,
|
||||||
|
vol.Optional(CONF_RECEIVE_TIMEOUT): cv.positive_time_period_milliseconds,
|
||||||
vol.Optional(CONF_SCAN): cv.boolean,
|
vol.Optional(CONF_SCAN): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -19,6 +21,10 @@ def to_code(config):
|
||||||
i2c = Pvariable('I2CComponent', config[CONF_ID], rhs)
|
i2c = Pvariable('I2CComponent', config[CONF_ID], rhs)
|
||||||
if CONF_FREQUENCY in config:
|
if CONF_FREQUENCY in config:
|
||||||
add(i2c.set_frequency(config[CONF_FREQUENCY]))
|
add(i2c.set_frequency(config[CONF_FREQUENCY]))
|
||||||
|
if CONF_RECEIVE_TIMEOUT in config:
|
||||||
|
add(i2c.set_receive_timeout(config[CONF_RECEIVE_TIMEOUT]))
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_I2C'
|
BUILD_FLAGS = '-DUSE_I2C'
|
||||||
|
|
||||||
|
LIB_DEPS = 'Wire'
|
||||||
|
|
|
@ -2,17 +2,16 @@ import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml import pins
|
from esphomeyaml import pins
|
||||||
from esphomeyaml.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN, ESP_PLATFORM_ESP32
|
from esphomeyaml.const import CONF_CARRIER_DUTY_PERCENT, CONF_ID, CONF_PIN
|
||||||
from esphomeyaml.helpers import App, Pvariable, exp_gpio_output_pin
|
from esphomeyaml.helpers import App, Pvariable, exp_gpio_output_pin
|
||||||
|
|
||||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
|
||||||
|
|
||||||
IR_TRANSMITTER_COMPONENT_CLASS = 'switch_::IRTransmitterComponent'
|
IR_TRANSMITTER_COMPONENT_CLASS = 'switch_::IRTransmitterComponent'
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||||
cv.GenerateID('ir_transmitter'): cv.register_variable_id,
|
cv.GenerateID('ir_transmitter'): cv.register_variable_id,
|
||||||
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
||||||
vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(vol.Coerce(int), vol.Range(min=0, max=100)),
|
vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(vol.Coerce(int),
|
||||||
|
vol.Range(min=0, max=100, min_included=False)),
|
||||||
})])
|
})])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH
|
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT
|
||||||
from esphomeyaml.helpers import add
|
from esphomeyaml.helpers import add
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
|
@ -10,6 +10,8 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||||
def setup_light_component(obj, config):
|
def setup_light_component(obj, config):
|
||||||
if CONF_DEFAULT_TRANSITION_LENGTH in config:
|
if CONF_DEFAULT_TRANSITION_LENGTH in config:
|
||||||
add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH]))
|
add(obj.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH]))
|
||||||
|
if CONF_GAMMA_CORRECT in config:
|
||||||
|
add(obj.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_LIGHT'
|
BUILD_FLAGS = '-DUSE_LIGHT'
|
||||||
|
|
98
esphomeyaml/components/light/fastled_clockless.py
Normal file
98
esphomeyaml/components/light/fastled_clockless.py
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml import pins, core
|
||||||
|
from esphomeyaml.components import light
|
||||||
|
from esphomeyaml.const import CONF_CHIPSET, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||||
|
CONF_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_RGB_ORDER, \
|
||||||
|
ESP_PLATFORM_ESP32
|
||||||
|
from esphomeyaml.helpers import App, TemplateArguments, add, setup_mqtt_component, variable, \
|
||||||
|
RawExpression
|
||||||
|
|
||||||
|
TYPES = [
|
||||||
|
'NEOPIXEL',
|
||||||
|
'TM1829',
|
||||||
|
'TM1809',
|
||||||
|
'TM1804',
|
||||||
|
'TM1803',
|
||||||
|
'UCS1903',
|
||||||
|
'UCS1903B',
|
||||||
|
'UCS1904',
|
||||||
|
'UCS2903',
|
||||||
|
'WS2812',
|
||||||
|
'WS2852',
|
||||||
|
'WS2812B',
|
||||||
|
'SK6812',
|
||||||
|
'SK6822',
|
||||||
|
'APA106',
|
||||||
|
'PL9823',
|
||||||
|
'WS2811',
|
||||||
|
'WS2813',
|
||||||
|
'APA104',
|
||||||
|
'WS2811_400',
|
||||||
|
'GW6205',
|
||||||
|
'GW6205_400',
|
||||||
|
'LPD1886',
|
||||||
|
'LPD1886_8BIT',
|
||||||
|
'PIXIE',
|
||||||
|
]
|
||||||
|
|
||||||
|
RGB_ORDERS = [
|
||||||
|
'RGB',
|
||||||
|
'RBG',
|
||||||
|
'GRB',
|
||||||
|
'GBR',
|
||||||
|
'BRG',
|
||||||
|
'BGR',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def validate(value):
|
||||||
|
if value[CONF_CHIPSET] == 'NEOPIXEL' and CONF_RGB_ORDER in value:
|
||||||
|
raise vol.Invalid("NEOPIXEL doesn't support RGB order")
|
||||||
|
if value[CONF_CHIPSET] == 'PIXIE' and core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
|
raise vol.Invalid("PIXIE lights are not supported with the ESP32")
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = vol.All(light.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('fast_led_clockless_light'): cv.register_variable_id,
|
||||||
|
|
||||||
|
vol.Required(CONF_CHIPSET): vol.All(vol.Upper, vol.Any(*TYPES)),
|
||||||
|
vol.Required(CONF_PIN): pins.output_pin,
|
||||||
|
|
||||||
|
vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||||
|
vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||||
|
vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, vol.Any(*RGB_ORDERS)),
|
||||||
|
|
||||||
|
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||||
|
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||||
|
}), validate)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_fast_led_light(config[CONF_NAME])
|
||||||
|
make = variable('Application::MakeFastLEDLight', config[CONF_ID], rhs)
|
||||||
|
fast_led = make.Pfast_led
|
||||||
|
|
||||||
|
rgb_order = None
|
||||||
|
if CONF_RGB_ORDER in config:
|
||||||
|
rgb_order = RawExpression(config[CONF_RGB_ORDER])
|
||||||
|
template_args = TemplateArguments(RawExpression(config[CONF_CHIPSET]),
|
||||||
|
config[CONF_PIN], rgb_order)
|
||||||
|
add(fast_led.add_leds(template_args, config[CONF_NUM_LEDS]))
|
||||||
|
|
||||||
|
if CONF_MAX_REFRESH_RATE in config:
|
||||||
|
add(fast_led.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
|
||||||
|
|
||||||
|
setup_mqtt_component(make.Pmqtt, config)
|
||||||
|
light.setup_light_component(make.Pstate, config)
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'
|
||||||
|
|
||||||
|
|
||||||
|
def required_build_flags(config):
|
||||||
|
if config[CONF_CHIPSET] == 'PIXIE':
|
||||||
|
return '-DUSE_FAST_LED_LIGHT_PIXIE'
|
||||||
|
return None
|
69
esphomeyaml/components/light/fastled_spi.py
Normal file
69
esphomeyaml/components/light/fastled_spi.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml import pins
|
||||||
|
from esphomeyaml.components import light
|
||||||
|
from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, \
|
||||||
|
CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, \
|
||||||
|
CONF_NUM_LEDS, CONF_RGB_ORDER
|
||||||
|
from esphomeyaml.helpers import App, TemplateArguments, add, setup_mqtt_component, variable, \
|
||||||
|
RawExpression
|
||||||
|
|
||||||
|
CHIPSETS = [
|
||||||
|
'LPD8806',
|
||||||
|
'WS2801',
|
||||||
|
'WS2803',
|
||||||
|
'SM16716',
|
||||||
|
'P9813',
|
||||||
|
'APA102',
|
||||||
|
'SK9822',
|
||||||
|
'DOTSTAR',
|
||||||
|
]
|
||||||
|
|
||||||
|
RGB_ORDERS = [
|
||||||
|
'RGB',
|
||||||
|
'RBG',
|
||||||
|
'GRB',
|
||||||
|
'GBR',
|
||||||
|
'BRG',
|
||||||
|
'BGR',
|
||||||
|
]
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('fast_led_spi_light'): cv.register_variable_id,
|
||||||
|
|
||||||
|
vol.Required(CONF_CHIPSET): vol.All(vol.Upper, vol.Any(*CHIPSETS)),
|
||||||
|
vol.Required(CONF_DATA_PIN): pins.output_pin,
|
||||||
|
vol.Required(CONF_CLOCK_PIN): pins.output_pin,
|
||||||
|
|
||||||
|
vol.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||||
|
vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, vol.Any(*RGB_ORDERS)),
|
||||||
|
vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||||
|
|
||||||
|
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||||
|
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_fast_led_light(config[CONF_NAME])
|
||||||
|
make = variable('Application::MakeFastLEDLight', config[CONF_ID], rhs)
|
||||||
|
fast_led = make.Pfast_led
|
||||||
|
|
||||||
|
rgb_order = None
|
||||||
|
if CONF_RGB_ORDER in config:
|
||||||
|
rgb_order = RawExpression(config[CONF_RGB_ORDER])
|
||||||
|
template_args = TemplateArguments(RawExpression(config[CONF_CHIPSET]),
|
||||||
|
config[CONF_DATA_PIN],
|
||||||
|
config[CONF_CLOCK_PIN],
|
||||||
|
rgb_order)
|
||||||
|
add(fast_led.add_leds(template_args, config[CONF_NUM_LEDS]))
|
||||||
|
|
||||||
|
if CONF_MAX_REFRESH_RATE in config:
|
||||||
|
add(fast_led.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
|
||||||
|
|
||||||
|
setup_mqtt_component(make.Pmqtt, config)
|
||||||
|
light.setup_light_component(make.Pstate, config)
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = 'DUSE_FAST_LED_LIGHT'
|
|
@ -4,13 +4,13 @@ import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.components import light
|
from esphomeyaml.components import light
|
||||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \
|
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \
|
||||||
CONF_NAME, CONF_OUTPUT
|
CONF_NAME, CONF_OUTPUT
|
||||||
from esphomeyaml.helpers import App, add, get_variable, variable, setup_mqtt_component
|
from esphomeyaml.helpers import App, get_variable, setup_mqtt_component, variable
|
||||||
|
|
||||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('monochromatic_light'): cv.register_variable_id,
|
cv.GenerateID('monochromatic_light'): cv.register_variable_id,
|
||||||
vol.Required(CONF_OUTPUT): cv.variable_id,
|
vol.Required(CONF_OUTPUT): cv.variable_id,
|
||||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period,
|
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,5 @@ def to_code(config):
|
||||||
output = get_variable(config[CONF_OUTPUT])
|
output = get_variable(config[CONF_OUTPUT])
|
||||||
rhs = App.make_monochromatic_light(config[CONF_NAME], output)
|
rhs = App.make_monochromatic_light(config[CONF_NAME], output)
|
||||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||||
if CONF_GAMMA_CORRECT in config:
|
|
||||||
add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
|
||||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||||
light.setup_light_component(light_struct.Pstate, config)
|
light.setup_light_component(light_struct.Pstate, config)
|
||||||
|
|
|
@ -12,7 +12,7 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_GREEN): cv.variable_id,
|
vol.Required(CONF_GREEN): cv.variable_id,
|
||||||
vol.Required(CONF_BLUE): cv.variable_id,
|
vol.Required(CONF_BLUE): cv.variable_id,
|
||||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period,
|
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,5 @@ def to_code(config):
|
||||||
blue = get_variable(config[CONF_BLUE])
|
blue = get_variable(config[CONF_BLUE])
|
||||||
rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue)
|
rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue)
|
||||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||||
if CONF_GAMMA_CORRECT in config:
|
|
||||||
add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
|
||||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||||
light.setup_light_component(light_struct.Pstate, 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.components import light
|
||||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||||
CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED, CONF_WHITE
|
CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED, CONF_WHITE
|
||||||
from esphomeyaml.helpers import App, add, get_variable, setup_mqtt_component, variable
|
from esphomeyaml.helpers import App, get_variable, setup_mqtt_component, variable
|
||||||
|
|
||||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('rgbw_light'): cv.register_variable_id,
|
cv.GenerateID('rgbw_light'): cv.register_variable_id,
|
||||||
|
@ -13,7 +13,7 @@ PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_BLUE): cv.variable_id,
|
vol.Required(CONF_BLUE): cv.variable_id,
|
||||||
vol.Required(CONF_WHITE): cv.variable_id,
|
vol.Required(CONF_WHITE): cv.variable_id,
|
||||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period,
|
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,5 @@ def to_code(config):
|
||||||
white = get_variable(config[CONF_WHITE])
|
white = get_variable(config[CONF_WHITE])
|
||||||
rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white)
|
rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white)
|
||||||
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
light_struct = variable('Application::MakeLight', config[CONF_ID], rhs)
|
||||||
if CONF_GAMMA_CORRECT in config:
|
|
||||||
add(light_struct.Poutput.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
|
||||||
setup_mqtt_component(light_struct.Pmqtt, config)
|
setup_mqtt_component(light_struct.Pmqtt, config)
|
||||||
light.setup_light_component(light_struct.Pstate, config)
|
light.setup_light_component(light_struct.Pstate, config)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGGER,
|
||||||
from esphomeyaml.core import ESPHomeYAMLError
|
from esphomeyaml.core import ESPHomeYAMLError
|
||||||
from esphomeyaml.helpers import App, Pvariable, RawExpression, add
|
from esphomeyaml.helpers import App, Pvariable, RawExpression, add
|
||||||
|
|
||||||
LOG_LEVELS = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE']
|
LOG_LEVELS = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE', 'VERY_VERBOSE']
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
is_log_level = vol.All(vol.Upper, vol.Any(*LOG_LEVELS))
|
is_log_level = vol.All(vol.Upper, vol.Any(*LOG_LEVELS))
|
||||||
|
|
|
@ -64,7 +64,7 @@ CONFIG_SCHEMA = vol.Schema({
|
||||||
vol.Optional(CONF_LOG_TOPIC): MQTT_MESSAGE_TEMPLATE_SCHEMA,
|
vol.Optional(CONF_LOG_TOPIC): MQTT_MESSAGE_TEMPLATE_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): vol.All(cv.positive_time_period, cv.time_period_to_seconds)
|
vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,3 +46,9 @@ def get_auth(config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_OTA'
|
BUILD_FLAGS = '-DUSE_OTA'
|
||||||
|
|
||||||
|
|
||||||
|
def lib_deps(config):
|
||||||
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
|
return ['ArduinoOTA', 'Update', 'ESPmDNS']
|
||||||
|
return ['Hash', 'ESP8266mDNS', 'ArduinoOTA']
|
||||||
|
|
|
@ -10,12 +10,16 @@ PHASE_BALANCERS = ['None', 'Linear', 'Weaved']
|
||||||
|
|
||||||
PCA9685_COMPONENT_TYPE = 'output::PCA9685OutputComponent'
|
PCA9685_COMPONENT_TYPE = 'output::PCA9685OutputComponent'
|
||||||
|
|
||||||
|
PHASE_BALANCER_MESSAGE = ("The phase_balancer option has been removed in version 1.5.0. "
|
||||||
|
"esphomelib will now automatically choose a suitable phase balancer.")
|
||||||
|
|
||||||
PCA9685_SCHEMA = vol.Schema({
|
PCA9685_SCHEMA = vol.Schema({
|
||||||
cv.GenerateID('pca9685'): cv.register_variable_id,
|
cv.GenerateID('pca9685'): cv.register_variable_id,
|
||||||
vol.Required(CONF_FREQUENCY): vol.All(cv.frequency,
|
vol.Required(CONF_FREQUENCY): vol.All(cv.frequency,
|
||||||
vol.Range(min=24, max=1526)),
|
vol.Range(min=23.84, max=1525.88)),
|
||||||
vol.Optional(CONF_PHASE_BALANCER): vol.All(vol.Title, vol.Any(*PHASE_BALANCERS)),
|
|
||||||
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||||
|
|
||||||
|
vol.Optional(CONF_PHASE_BALANCER): cv.invalid(PHASE_BALANCER_MESSAGE),
|
||||||
})
|
})
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCA9685_SCHEMA])
|
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCA9685_SCHEMA])
|
||||||
|
|
|
@ -7,8 +7,8 @@ from esphomeyaml.helpers import App, Pvariable, add, exp_gpio_output_pin
|
||||||
|
|
||||||
POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({
|
POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({
|
||||||
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
||||||
vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period,
|
vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period_milliseconds,
|
||||||
vol.Optional(CONF_KEEP_ON_TIME): cv.positive_time_period,
|
vol.Optional(CONF_KEEP_ON_TIME): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA])
|
CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA])
|
||||||
|
|
|
@ -37,7 +37,7 @@ MQTT_SENSOR_SCHEMA = vol.Schema({
|
||||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
|
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
|
||||||
vol.Optional(CONF_ICON): cv.icon,
|
vol.Optional(CONF_ICON): cv.icon,
|
||||||
vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int),
|
vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int),
|
||||||
vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period),
|
vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period_milliseconds),
|
||||||
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA
|
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('adc'): cv.register_variable_id,
|
cv.GenerateID('adc'): cv.register_variable_id,
|
||||||
vol.Required(CONF_PIN): pins.analog_pin,
|
vol.Required(CONF_PIN): pins.analog_pin,
|
||||||
vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, ATTENUATION_MODE_SCHEMA),
|
vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, ATTENUATION_MODE_SCHEMA),
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,23 +9,23 @@ from esphomeyaml.helpers import RawExpression, get_variable, Pvariable
|
||||||
DEPENDENCIES = ['ads1115']
|
DEPENDENCIES = ['ads1115']
|
||||||
|
|
||||||
MUX = {
|
MUX = {
|
||||||
'A0_A1': 'ADS1115_MUX_P0_N1',
|
'A0_A1': 'sensor::ADS1115_MULTIPLEXER_P0_N1',
|
||||||
'A0_A3': 'ADS1115_MUX_P0_N3',
|
'A0_A3': 'sensor::ADS1115_MULTIPLEXER_P0_N3',
|
||||||
'A1_A3': 'ADS1115_MUX_P1_N3',
|
'A1_A3': 'sensor::ADS1115_MULTIPLEXER_P1_N3',
|
||||||
'A2_A3': 'ADS1115_MUX_P2_N3',
|
'A2_A3': 'sensor::ADS1115_MULTIPLEXER_P2_N3',
|
||||||
'A0_GND': 'ADS1115_MUX_P0_NG',
|
'A0_GND': 'sensor::ADS1115_MULTIPLEXER_P0_NG',
|
||||||
'A1_GND': 'ADS1115_MUX_P1_NG',
|
'A1_GND': 'sensor::ADS1115_MULTIPLEXER_P1_NG',
|
||||||
'A2_GND': 'ADS1115_MUX_P2_NG',
|
'A2_GND': 'sensor::ADS1115_MULTIPLEXER_P2_NG',
|
||||||
'A3_GND': 'ADS1115_MUX_P3_NG',
|
'A3_GND': 'sensor::ADS1115_MULTIPLEXER_P3_NG',
|
||||||
}
|
}
|
||||||
|
|
||||||
GAIN = {
|
GAIN = {
|
||||||
'6.144': 'ADS1115_PGA_6P144',
|
'6.144': 'sensor::ADS1115_GAIN_6P144',
|
||||||
'4.096': 'ADS1115_PGA_6P096',
|
'4.096': 'sensor::ADS1115_GAIN_6P096',
|
||||||
'2.048': 'ADS1115_PGA_2P048',
|
'2.048': 'sensor::ADS1115_GAIN_2P048',
|
||||||
'1.024': 'ADS1115_PGA_1P024',
|
'1.024': 'sensor::ADS1115_GAIN_1P024',
|
||||||
'0.512': 'ADS1115_PGA_0P512',
|
'0.512': 'sensor::ADS1115_GAIN_0P512',
|
||||||
'0.256': 'ADS1115_PGA_0P256',
|
'0.256': 'sensor::ADS1115_GAIN_0P256',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_MULTIPLEXER): vol.All(vol.Upper, vol.Any(*list(MUX.keys()))),
|
vol.Required(CONF_MULTIPLEXER): vol.All(vol.Upper, vol.Any(*list(MUX.keys()))),
|
||||||
vol.Required(CONF_GAIN): validate_gain,
|
vol.Required(CONF_GAIN): validate_gain,
|
||||||
vol.Optional(CONF_ADS1115_ID): cv.variable_id,
|
vol.Optional(CONF_ADS1115_ID): cv.variable_id,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
}).extend(sensor.MQTT_SENSOR_ID_SCHEMA.schema)
|
}).extend(sensor.MQTT_SENSOR_ID_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
|
37
esphomeyaml/components/sensor/bh1750.py
Normal file
37
esphomeyaml/components/sensor/bh1750.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml.components import sensor
|
||||||
|
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_RESOLUTION, \
|
||||||
|
CONF_UPDATE_INTERVAL
|
||||||
|
from esphomeyaml.helpers import App, RawExpression, add, variable
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
|
BH1750_RESOLUTIONS = {
|
||||||
|
4.0: 'sensor::BH1750_RESOLUTION_4P0_LX',
|
||||||
|
1.0: 'sensor::BH1750_RESOLUTION_1P0_LX',
|
||||||
|
0.5: 'sensor::BH1750_RESOLUTION_0P5_LX',
|
||||||
|
}
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('bh1750_sensor'): cv.register_variable_id,
|
||||||
|
vol.Optional(CONF_ADDRESS, default=0x23): cv.i2c_address,
|
||||||
|
vol.Optional(CONF_RESOLUTION): vol.All(cv.positive_float, vol.Any(*BH1750_RESOLUTIONS)),
|
||||||
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_bh1750_sensor(config[CONF_NAME], config[CONF_ADDRESS],
|
||||||
|
config.get(CONF_UPDATE_INTERVAL))
|
||||||
|
make_bh1750 = variable('Application::MakeBH1750Sensor', config[CONF_ID], rhs)
|
||||||
|
bh1750 = make_bh1750.Pbh1750
|
||||||
|
if CONF_RESOLUTION in config:
|
||||||
|
constant = BH1750_RESOLUTIONS[config[CONF_RESOLUTION]]
|
||||||
|
add(bh1750.set_resolution(RawExpression(constant)))
|
||||||
|
sensor.setup_sensor(bh1750, config)
|
||||||
|
sensor.setup_mqtt_sensor_component(make_bh1750.Pmqtt, config)
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_BH1750'
|
75
esphomeyaml/components/sensor/bme280.py
Normal file
75
esphomeyaml/components/sensor/bme280.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml.components import sensor
|
||||||
|
from esphomeyaml.components.sensor import MQTT_SENSOR_SCHEMA
|
||||||
|
from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_NAME, \
|
||||||
|
CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
||||||
|
from esphomeyaml.helpers import App, RawExpression, add, variable
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
|
OVERSAMPLING_OPTIONS = {
|
||||||
|
'NONE': 'sensor::BME280_OVERSAMPLING_NONE',
|
||||||
|
'1X': 'sensor::BME280_OVERSAMPLING_1X',
|
||||||
|
'2X': 'sensor::BME280_OVERSAMPLING_2X',
|
||||||
|
'4X': 'sensor::BME280_OVERSAMPLING_4X',
|
||||||
|
'8X': 'sensor::BME280_OVERSAMPLING_8X',
|
||||||
|
'16X': 'sensor::BME280_OVERSAMPLING_16X',
|
||||||
|
}
|
||||||
|
|
||||||
|
IIR_FILTER_OPTIONS = {
|
||||||
|
'OFF': 'sensor::BME280_IIR_FILTER_OFF',
|
||||||
|
'2X': 'sensor::BME280_IIR_FILTER_2X',
|
||||||
|
'4X': 'sensor::BME280_IIR_FILTER_4X',
|
||||||
|
'8X': 'sensor::BME280_IIR_FILTER_8X',
|
||||||
|
'16X': 'sensor::BME280_IIR_FILTER_16X',
|
||||||
|
}
|
||||||
|
|
||||||
|
BME280_OVERSAMPLING_SENSOR_SCHEMA = MQTT_SENSOR_SCHEMA.extend({
|
||||||
|
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, vol.Any(*OVERSAMPLING_OPTIONS)),
|
||||||
|
})
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('bme280'): cv.register_variable_id,
|
||||||
|
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
|
||||||
|
vol.Required(CONF_TEMPERATURE): BME280_OVERSAMPLING_SENSOR_SCHEMA,
|
||||||
|
vol.Required(CONF_PRESSURE): BME280_OVERSAMPLING_SENSOR_SCHEMA,
|
||||||
|
vol.Required(CONF_HUMIDITY): BME280_OVERSAMPLING_SENSOR_SCHEMA,
|
||||||
|
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, vol.Any(*IIR_FILTER_OPTIONS)),
|
||||||
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_bme280_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||||
|
config[CONF_PRESSURE][CONF_NAME],
|
||||||
|
config[CONF_HUMIDITY][CONF_NAME],
|
||||||
|
config[CONF_ADDRESS],
|
||||||
|
config.get(CONF_UPDATE_INTERVAL))
|
||||||
|
make = variable('Application::MakeBME280Sensor', config[CONF_ID], rhs)
|
||||||
|
bme280 = make.Pbme280
|
||||||
|
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
|
||||||
|
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
|
||||||
|
add(bme280.set_temperature_oversampling(RawExpression(constant)))
|
||||||
|
if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
|
||||||
|
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
|
||||||
|
add(bme280.set_pressure_oversampling(RawExpression(constant)))
|
||||||
|
if CONF_OVERSAMPLING in config[CONF_HUMIDITY]:
|
||||||
|
constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]]
|
||||||
|
add(bme280.set_humidity_oversampling(RawExpression(constant)))
|
||||||
|
if CONF_IIR_FILTER in config:
|
||||||
|
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
|
||||||
|
add(bme280.set_iir_filter(RawExpression(constant)))
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme280.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_temperature, config[CONF_TEMPERATURE])
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme280.Pget_pressure_sensor(), config[CONF_PRESSURE])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_pressure, config[CONF_PRESSURE])
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme280.Pget_humidity_sensor(), config[CONF_HUMIDITY])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_BME280'
|
84
esphomeyaml/components/sensor/bme680.py
Normal file
84
esphomeyaml/components/sensor/bme680.py
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml.components import sensor
|
||||||
|
from esphomeyaml.components.sensor import MQTT_SENSOR_SCHEMA
|
||||||
|
from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_NAME, \
|
||||||
|
CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL, CONF_GAS_RESISTANCE
|
||||||
|
from esphomeyaml.helpers import App, RawExpression, add, variable
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
|
OVERSAMPLING_OPTIONS = {
|
||||||
|
'NONE': 'sensor::BME680_OVERSAMPLING_NONE',
|
||||||
|
'1X': 'sensor::BME680_OVERSAMPLING_1X',
|
||||||
|
'2X': 'sensor::BME680_OVERSAMPLING_2X',
|
||||||
|
'4X': 'sensor::BME680_OVERSAMPLING_4X',
|
||||||
|
'8X': 'sensor::BME680_OVERSAMPLING_8X',
|
||||||
|
'16X': 'sensor::BME680_OVERSAMPLING_16X',
|
||||||
|
}
|
||||||
|
|
||||||
|
IIR_FILTER_OPTIONS = {
|
||||||
|
'OFF': 'sensor::BME680_IIR_FILTER_OFF',
|
||||||
|
'1X': 'sensor::BME680_IIR_FILTER_1X',
|
||||||
|
'3X': 'sensor::BME680_IIR_FILTER_3X',
|
||||||
|
'7X': 'sensor::BME680_IIR_FILTER_7X',
|
||||||
|
'15X': 'sensor::BME680_IIR_FILTER_15X',
|
||||||
|
'31X': 'sensor::BME680_IIR_FILTER_31X',
|
||||||
|
'63X': 'sensor::BME680_IIR_FILTER_63X',
|
||||||
|
'127X': 'sensor::BME680_IIR_FILTER_127X',
|
||||||
|
}
|
||||||
|
|
||||||
|
BME680_OVERSAMPLING_SENSOR_SCHEMA = MQTT_SENSOR_SCHEMA.extend({
|
||||||
|
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, vol.Any(*OVERSAMPLING_OPTIONS)),
|
||||||
|
})
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('bme680'): cv.register_variable_id,
|
||||||
|
vol.Optional(CONF_ADDRESS, default=0x76): cv.i2c_address,
|
||||||
|
vol.Required(CONF_TEMPERATURE): BME680_OVERSAMPLING_SENSOR_SCHEMA,
|
||||||
|
vol.Required(CONF_PRESSURE): BME680_OVERSAMPLING_SENSOR_SCHEMA,
|
||||||
|
vol.Required(CONF_HUMIDITY): BME680_OVERSAMPLING_SENSOR_SCHEMA,
|
||||||
|
vol.Required(CONF_GAS_RESISTANCE): MQTT_SENSOR_SCHEMA,
|
||||||
|
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, vol.Any(*IIR_FILTER_OPTIONS)),
|
||||||
|
# TODO: Heater
|
||||||
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_bme680_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||||
|
config[CONF_PRESSURE][CONF_NAME],
|
||||||
|
config[CONF_HUMIDITY][CONF_NAME],
|
||||||
|
config[CONF_GAS_RESISTANCE][CONF_NAME],
|
||||||
|
config[CONF_ADDRESS],
|
||||||
|
config.get(CONF_UPDATE_INTERVAL))
|
||||||
|
make = variable('Application::MakeBME680Sensor', config[CONF_ID], rhs)
|
||||||
|
bme680 = make.Pbme680
|
||||||
|
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
|
||||||
|
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
|
||||||
|
add(bme680.set_temperature_oversampling(RawExpression(constant)))
|
||||||
|
if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
|
||||||
|
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
|
||||||
|
add(bme680.set_pressure_oversampling(RawExpression(constant)))
|
||||||
|
if CONF_OVERSAMPLING in config[CONF_HUMIDITY]:
|
||||||
|
constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]]
|
||||||
|
add(bme680.set_humidity_oversampling(RawExpression(constant)))
|
||||||
|
if CONF_IIR_FILTER in config:
|
||||||
|
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
|
||||||
|
add(bme680.set_iir_filter(RawExpression(constant)))
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme680.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_temperature, config[CONF_TEMPERATURE])
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme680.Pget_pressure_sensor(), config[CONF_PRESSURE])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_pressure, config[CONF_PRESSURE])
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme680.Pget_humidity_sensor(), config[CONF_HUMIDITY])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||||
|
|
||||||
|
sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), config[CONF_GAS_RESISTANCE])
|
||||||
|
sensor.setup_mqtt_sensor_component(make.Pmqtt_gas_resistance, config[CONF_GAS_RESISTANCE])
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_BME680'
|
|
@ -14,7 +14,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Required(CONF_PRESSURE): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_PRESSURE): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,13 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAM
|
||||||
CONF_UPDATE_INTERVAL, CONF_ID
|
CONF_UPDATE_INTERVAL, CONF_ID
|
||||||
from esphomeyaml.helpers import HexIntLiteral, get_variable, Pvariable
|
from esphomeyaml.helpers import HexIntLiteral, get_variable, Pvariable
|
||||||
|
|
||||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('dallas_sensor'): cv.register_variable_id,
|
cv.GenerateID('dallas_sensor'): cv.register_variable_id,
|
||||||
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
|
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
|
||||||
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
|
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
|
||||||
vol.Optional(CONF_DALLAS_ID): cv.variable_id,
|
vol.Optional(CONF_DALLAS_ID): cv.variable_id,
|
||||||
vol.Optional(CONF_RESOLUTION): vol.All(vol.Coerce(int), vol.Range(min=8, max=12)),
|
vol.Optional(CONF_RESOLUTION): vol.All(vol.Coerce(int), vol.Range(min=8, max=12)),
|
||||||
}).extend(sensor.MQTT_SENSOR_ID_SCHEMA.schema)
|
}).extend(sensor.MQTT_SENSOR_ID_SCHEMA.schema), cv.has_at_least_one_key(CONF_ADDRESS, CONF_INDEX))
|
||||||
|
|
||||||
|
|
||||||
def to_code(config):
|
def to_code(config):
|
||||||
|
|
|
@ -1,33 +1,40 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml import pins
|
|
||||||
from esphomeyaml.components import sensor
|
from esphomeyaml.components import sensor
|
||||||
from esphomeyaml.components.sensor import MQTT_SENSOR_SCHEMA
|
from esphomeyaml.components.sensor import MQTT_SENSOR_SCHEMA
|
||||||
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \
|
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \
|
||||||
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
||||||
from esphomeyaml.helpers import App, RawExpression, add, variable
|
from esphomeyaml.helpers import App, RawExpression, add, variable, exp_gpio_output_pin
|
||||||
|
from esphomeyaml.pins import GPIO_OUTPUT_PIN_SCHEMA
|
||||||
|
|
||||||
DHT_MODELS = ['AUTO_DETECT', 'DHT11', 'DHT22', 'AM2302', 'RHT03']
|
DHT_MODELS = {
|
||||||
|
'AUTO_DETECT': 'sensor::DHT_MODEL_AUTO_DETECT',
|
||||||
|
'DHT11': 'sensor::DHT_MODEL_DHT11',
|
||||||
|
'DHT22': 'sensor::DHT_MODEL_DHT22',
|
||||||
|
'AM2302': 'sensor::DHT_MODEL_AM2302',
|
||||||
|
'RHT03': 'sensor::DHT_MODEL_RHT03',
|
||||||
|
}
|
||||||
|
|
||||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('dht_sensor'): cv.register_variable_id,
|
cv.GenerateID('dht_sensor'): cv.register_variable_id,
|
||||||
vol.Required(CONF_PIN): pins.input_output_pin,
|
vol.Required(CONF_PIN): GPIO_OUTPUT_PIN_SCHEMA,
|
||||||
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Optional(CONF_MODEL): vol.All(vol.Upper, vol.Any(*DHT_MODELS)),
|
vol.Optional(CONF_MODEL): vol.All(vol.Upper, vol.Any(*DHT_MODELS)),
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def to_code(config):
|
def to_code(config):
|
||||||
|
pin = exp_gpio_output_pin(config[CONF_PIN])
|
||||||
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||||
config[CONF_HUMIDITY][CONF_NAME],
|
config[CONF_HUMIDITY][CONF_NAME],
|
||||||
config[CONF_PIN], config.get(CONF_UPDATE_INTERVAL))
|
pin, config.get(CONF_UPDATE_INTERVAL))
|
||||||
dht = variable('Application::MakeDHTSensor', config[CONF_ID], rhs)
|
dht = variable('Application::MakeDHTSensor', config[CONF_ID], rhs)
|
||||||
if CONF_MODEL in config:
|
if CONF_MODEL in config:
|
||||||
model = RawExpression('DHT::{}'.format(config[CONF_MODEL]))
|
constant = DHT_MODELS[config[CONF_MODEL]]
|
||||||
add(dht.Pdht.set_dht_model(model))
|
add(dht.Pdht.set_dht_model(RawExpression(constant)))
|
||||||
sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
|
sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
|
||||||
sensor.setup_mqtt_sensor_component(dht.Pmqtt_temperature, 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_sensor(dht.Pdht.Pget_humidity_sensor(), config[CONF_HUMIDITY])
|
||||||
|
|
|
@ -13,7 +13,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('dht_sensor'): cv.register_variable_id,
|
cv.GenerateID('dht_sensor'): cv.register_variable_id,
|
||||||
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('htu21d'): cv.register_variable_id,
|
cv.GenerateID('htu21d'): cv.register_variable_id,
|
||||||
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_TEMPERATURE): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
vol.Required(CONF_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
vol.Optional(CONF_GYRO_Y): MQTT_SENSOR_ID_SCHEMA,
|
vol.Optional(CONF_GYRO_Y): MQTT_SENSOR_ID_SCHEMA,
|
||||||
vol.Optional(CONF_GYRO_Z): MQTT_SENSOR_ID_SCHEMA,
|
vol.Optional(CONF_GYRO_Z): MQTT_SENSOR_ID_SCHEMA,
|
||||||
vol.Optional(CONF_TEMPERATURE): MQTT_SENSOR_ID_SCHEMA,
|
vol.Optional(CONF_TEMPERATURE): MQTT_SENSOR_ID_SCHEMA,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA,
|
vol.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA,
|
||||||
}),
|
}),
|
||||||
vol.Optional(CONF_INTERNAL_FILTER): vol.All(vol.Coerce(int), vol.Range(min=0, max=1023)),
|
vol.Optional(CONF_INTERNAL_FILTER): vol.All(vol.Coerce(int), vol.Range(min=0, max=1023)),
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
|
52
esphomeyaml/components/sensor/tsl2561.py
Normal file
52
esphomeyaml/components/sensor/tsl2561.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml.components import sensor
|
||||||
|
from esphomeyaml.const import CONF_ADDRESS, CONF_GAIN, CONF_ID, CONF_INTEGRATION_TIME, CONF_NAME, \
|
||||||
|
CONF_UPDATE_INTERVAL
|
||||||
|
from esphomeyaml.core import TimePeriod
|
||||||
|
from esphomeyaml.helpers import App, RawExpression, add, variable
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
|
INTEGRATION_TIMES = {
|
||||||
|
TimePeriod(milliseconds=14): 'sensor::TSL2561_INTEGRATION_14MS',
|
||||||
|
TimePeriod(milliseconds=101): 'sensor::TSL2561_INTEGRATION_101MS',
|
||||||
|
TimePeriod(milliseconds=402): 'sensor::TSL2561_INTEGRATION_402MS',
|
||||||
|
}
|
||||||
|
GAINS = {
|
||||||
|
'1X': 'sensor::TSL2561_GAIN_1X',
|
||||||
|
'16X': 'sensor::TSL2561_GAIN_16X',
|
||||||
|
}
|
||||||
|
|
||||||
|
CONF_IS_CS_PACKAGE = 'is_cs_package'
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
|
cv.GenerateID('tsl2561_sensor'): cv.register_variable_id,
|
||||||
|
vol.Optional(CONF_ADDRESS, default=0x39): cv.i2c_address,
|
||||||
|
vol.Optional(CONF_INTEGRATION_TIME): vol.All(cv.positive_time_period_milliseconds,
|
||||||
|
vol.Any(*INTEGRATION_TIMES)),
|
||||||
|
vol.Optional(CONF_GAIN): vol.All(vol.Upper, vol.Any(*GAINS)),
|
||||||
|
vol.Optional(CONF_IS_CS_PACKAGE): cv.boolean,
|
||||||
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
rhs = App.make_tsl2561_sensor(config[CONF_NAME], config[CONF_ADDRESS],
|
||||||
|
config.get(CONF_UPDATE_INTERVAL))
|
||||||
|
make_tsl = variable('Application::MakeTSL2561Sensor', config[CONF_ID], rhs)
|
||||||
|
tsl2561 = make_tsl.Ptsl2561
|
||||||
|
if CONF_INTEGRATION_TIME in config:
|
||||||
|
constant = INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]]
|
||||||
|
add(tsl2561.set_integration_time(RawExpression(constant)))
|
||||||
|
if CONF_GAIN in config:
|
||||||
|
constant = GAINS[config[CONF_GAIN]]
|
||||||
|
add(tsl2561.set_gain(RawExpression(constant)))
|
||||||
|
if CONF_IS_CS_PACKAGE in config:
|
||||||
|
add(tsl2561.set_is_cs_package(config[CONF_IS_CS_PACKAGE]))
|
||||||
|
sensor.setup_sensor(tsl2561, config)
|
||||||
|
sensor.setup_mqtt_sensor_component(make_tsl.Pmqtt, config)
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_FLAGS = '-DUSE_TSL2561'
|
|
@ -13,8 +13,8 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_TRIGGER_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
vol.Required(CONF_TRIGGER_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
||||||
vol.Required(CONF_ECHO_PIN): pins.GPIO_INPUT_PIN_SCHEMA,
|
vol.Required(CONF_ECHO_PIN): pins.GPIO_INPUT_PIN_SCHEMA,
|
||||||
vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float,
|
vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float,
|
||||||
vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_int,
|
vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_time_period_microseconds,
|
||||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||||
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,20 @@ import voluptuous as vol
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.components import switch
|
from esphomeyaml.components import switch
|
||||||
from esphomeyaml.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS
|
from esphomeyaml.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS
|
||||||
from esphomeyaml.const import CONF_ADDRESS, CONF_COMMAND, CONF_DATA, CONF_IR_TRANSMITTER_ID, \
|
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \
|
||||||
CONF_LG, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_REPEAT, CONF_SONY, CONF_TIMES, \
|
CONF_ID, CONF_IR_TRANSMITTER_ID, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, \
|
||||||
CONF_WAIT_TIME_US, CONF_RAW, CONF_CARRIER_FREQUENCY, CONF_NAME, CONF_ID
|
CONF_RAW, CONF_REPEAT, CONF_SONY, CONF_TIMES, CONF_WAIT_TIME
|
||||||
from esphomeyaml.core import ESPHomeYAMLError
|
from esphomeyaml.core import ESPHomeYAMLError
|
||||||
from esphomeyaml.helpers import HexIntLiteral, MockObj, get_variable, ArrayInitializer, Pvariable
|
from esphomeyaml.helpers import ArrayInitializer, HexIntLiteral, MockObj, Pvariable, get_variable
|
||||||
|
|
||||||
PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
DEPENDENCIES = ['ir_transmitter']
|
||||||
|
|
||||||
|
IR_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_RAW]
|
||||||
|
|
||||||
|
WAIT_TIME_MESSAGE = "The wait_time_us option has been renamed to wait_time in order to decrease " \
|
||||||
|
"ambiguity. "
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = vol.All(switch.PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID('ir_transmitter_switch'): cv.register_variable_id,
|
cv.GenerateID('ir_transmitter_switch'): cv.register_variable_id,
|
||||||
vol.Exclusive(CONF_NEC, 'code'): vol.Schema({
|
vol.Exclusive(CONF_NEC, 'code'): vol.Schema({
|
||||||
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
||||||
|
@ -33,11 +40,12 @@ PLATFORM_SCHEMA = switch.PLATFORM_SCHEMA.extend({
|
||||||
}),
|
}),
|
||||||
vol.Optional(CONF_REPEAT): vol.Any(cv.positive_not_null_int, vol.Schema({
|
vol.Optional(CONF_REPEAT): vol.Any(cv.positive_not_null_int, vol.Schema({
|
||||||
vol.Required(CONF_TIMES): cv.positive_not_null_int,
|
vol.Required(CONF_TIMES): cv.positive_not_null_int,
|
||||||
vol.Required(CONF_WAIT_TIME_US): cv.uint32_t,
|
vol.Required(CONF_WAIT_TIME): cv.positive_time_period_microseconds,
|
||||||
|
|
||||||
|
vol.Optional('wait_time_us'): cv.invalid(WAIT_TIME_MESSAGE),
|
||||||
})),
|
})),
|
||||||
vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id,
|
vol.Optional(CONF_IR_TRANSMITTER_ID): cv.variable_id,
|
||||||
}).extend(switch.MQTT_SWITCH_ID_SCHEMA.schema)
|
}).extend(switch.MQTT_SWITCH_ID_SCHEMA.schema), cv.has_at_least_one_key(*IR_KEYS))
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
SendData = MockObj('switch_::ir::SendData', '::')
|
SendData = MockObj('switch_::ir::SendData', '::')
|
||||||
|
@ -77,7 +85,7 @@ def exp_send_data(config):
|
||||||
wait_us = None
|
wait_us = None
|
||||||
else:
|
else:
|
||||||
times = config[CONF_REPEAT][CONF_TIMES]
|
times = config[CONF_REPEAT][CONF_TIMES]
|
||||||
wait_us = config[CONF_REPEAT][CONF_WAIT_TIME_US]
|
wait_us = config[CONF_REPEAT][CONF_WAIT_TIME]
|
||||||
base = MockObj(unicode(base), u'.')
|
base = MockObj(unicode(base), u'.')
|
||||||
base = base.repeat(times, wait_us)
|
base = base.repeat(times, wait_us)
|
||||||
return base
|
return base
|
||||||
|
|
|
@ -3,7 +3,8 @@ import logging
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID
|
from esphomeyaml import core
|
||||||
|
from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID, ESP_PLATFORM_ESP32
|
||||||
from esphomeyaml.helpers import App, add, Pvariable
|
from esphomeyaml.helpers import App, add, Pvariable
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -26,3 +27,9 @@ def to_code(config):
|
||||||
|
|
||||||
|
|
||||||
BUILD_FLAGS = '-DUSE_WEB_SERVER'
|
BUILD_FLAGS = '-DUSE_WEB_SERVER'
|
||||||
|
|
||||||
|
|
||||||
|
def lib_deps(config):
|
||||||
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
|
return 'FS'
|
||||||
|
return ''
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
|
from esphomeyaml import core
|
||||||
from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_GATEWAY, \
|
from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_GATEWAY, \
|
||||||
CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET
|
CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, \
|
||||||
|
ESP_PLATFORM_ESP8266
|
||||||
from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add
|
from esphomeyaml.helpers import App, MockObj, Pvariable, StructInitializer, add
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,3 +89,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]))
|
||||||
|
|
||||||
|
|
||||||
|
def lib_deps(config):
|
||||||
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||||
|
return 'ESP8266WiFi'
|
||||||
|
return None
|
||||||
|
|
|
@ -25,7 +25,7 @@ CORE_SCHEMA = vol.Schema({
|
||||||
vol.Required(CONF_BOARD): cv.string,
|
vol.Required(CONF_BOARD): cv.string,
|
||||||
vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string,
|
vol.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string,
|
||||||
vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean,
|
vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean,
|
||||||
vol.Optional(CONF_USE_BUILD_FLAGS, default=False): cv.boolean,
|
vol.Optional(CONF_USE_BUILD_FLAGS, default=True): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
REQUIRED_COMPONENTS = [
|
REQUIRED_COMPONENTS = [
|
||||||
|
|
|
@ -4,7 +4,6 @@ from __future__ import print_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
@ -13,7 +12,8 @@ from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOV
|
||||||
CONF_NAME, CONF_PAYLOAD_AVAILABLE, \
|
CONF_NAME, CONF_PAYLOAD_AVAILABLE, \
|
||||||
CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \
|
CONF_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \
|
||||||
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||||
from esphomeyaml.core import HexInt, IPAddress
|
from esphomeyaml.core import HexInt, IPAddress, TimePeriod, TimePeriodMilliseconds, \
|
||||||
|
TimePeriodMicroseconds, TimePeriodSeconds
|
||||||
from esphomeyaml.helpers import ensure_unique_string
|
from esphomeyaml.helpers import ensure_unique_string
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -178,19 +178,28 @@ def has_at_least_one_key(*keys):
|
||||||
return validate
|
return validate
|
||||||
|
|
||||||
|
|
||||||
TIME_PERIOD_ERROR = "Time period {} should be format 5ms, 5s, 5min, 5h"
|
TIME_PERIOD_ERROR = "Time period {} should be format number + unit, for example 5ms, 5s, 5min, 5h"
|
||||||
|
|
||||||
time_period_dict = vol.All(
|
time_period_dict = vol.All(
|
||||||
dict, vol.Schema({
|
dict, vol.Schema({
|
||||||
'days': vol.Coerce(int),
|
'days': vol.Coerce(float),
|
||||||
'hours': vol.Coerce(int),
|
'hours': vol.Coerce(float),
|
||||||
'minutes': vol.Coerce(int),
|
'minutes': vol.Coerce(float),
|
||||||
'seconds': vol.Coerce(int),
|
'seconds': vol.Coerce(float),
|
||||||
'milliseconds': vol.Coerce(int),
|
'milliseconds': vol.Coerce(float),
|
||||||
|
'microseconds': vol.Coerce(float),
|
||||||
}),
|
}),
|
||||||
has_at_least_one_key('days', 'hours', 'minutes',
|
has_at_least_one_key('days', 'hours', 'minutes',
|
||||||
'seconds', 'milliseconds'),
|
'seconds', 'milliseconds', 'microseconds'),
|
||||||
lambda value: timedelta(**value))
|
lambda value: TimePeriod(**value))
|
||||||
|
|
||||||
|
|
||||||
|
TIME_PERIOD_EXPLICIT_MESSAGE = ("The old way of being able to write time values without a "
|
||||||
|
"time unit (like \"1000\" for 1000 milliseconds) has been "
|
||||||
|
"removed in 1.5.0 as it was ambiguous in some places. Please "
|
||||||
|
"now explicitly specify the time unit (like \"1000ms\"). See "
|
||||||
|
"https://esphomelib.com/esphomeyaml/configuration-types.html#time "
|
||||||
|
"for more information.")
|
||||||
|
|
||||||
|
|
||||||
def time_period_str_colon(value):
|
def time_period_str_colon(value):
|
||||||
|
@ -220,7 +229,7 @@ def time_period_str_colon(value):
|
||||||
else:
|
else:
|
||||||
raise vol.Invalid(TIME_PERIOD_ERROR.format(value))
|
raise vol.Invalid(TIME_PERIOD_ERROR.format(value))
|
||||||
|
|
||||||
offset = timedelta(hours=hour, minutes=minute, seconds=second)
|
offset = TimePeriod(hours=hour, minutes=minute, seconds=second)
|
||||||
|
|
||||||
if negative_offset:
|
if negative_offset:
|
||||||
offset *= -1
|
offset *= -1
|
||||||
|
@ -232,10 +241,19 @@ def time_period_str_unit(value):
|
||||||
"""Validate and transform time period with time unit and integer value."""
|
"""Validate and transform time period with time unit and integer value."""
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
value = str(value)
|
value = str(value)
|
||||||
elif not isinstance(value, str):
|
elif not isinstance(value, (str, unicode)):
|
||||||
raise vol.Invalid("Expected string for time period with unit.")
|
raise vol.Invalid("Expected string for time period with unit.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
float(value)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise vol.Invalid(TIME_PERIOD_EXPLICIT_MESSAGE)
|
||||||
|
|
||||||
unit_to_kwarg = {
|
unit_to_kwarg = {
|
||||||
|
'us': 'microseconds',
|
||||||
|
'microseconds': 'microseconds',
|
||||||
'ms': 'milliseconds',
|
'ms': 'milliseconds',
|
||||||
'milliseconds': 'milliseconds',
|
'milliseconds': 'milliseconds',
|
||||||
's': 'seconds',
|
's': 'seconds',
|
||||||
|
@ -256,51 +274,56 @@ def time_period_str_unit(value):
|
||||||
u"got {}".format(value))
|
u"got {}".format(value))
|
||||||
|
|
||||||
kwarg = unit_to_kwarg[match.group(2)]
|
kwarg = unit_to_kwarg[match.group(2)]
|
||||||
return timedelta(**{kwarg: float(match.group(1))})
|
return TimePeriod(**{kwarg: float(match.group(1))})
|
||||||
|
|
||||||
|
|
||||||
def time_period_to_milliseconds(value):
|
def time_period_in_milliseconds(value):
|
||||||
if isinstance(value, (int, long)):
|
if value.microseconds is not None and value.microseconds != 0:
|
||||||
return value
|
raise vol.Invalid("Maximum precision is milliseconds")
|
||||||
if isinstance(value, float):
|
return TimePeriodMilliseconds(**value.as_dict())
|
||||||
return int(value)
|
|
||||||
return int(value.total_seconds() * 1000)
|
|
||||||
|
|
||||||
|
|
||||||
def time_period_to_seconds(value):
|
def time_period_in_microseconds(value):
|
||||||
if value / 1000 != value // 1000:
|
return TimePeriodMicroseconds(**value.as_dict())
|
||||||
raise vol.Invalid("Fractions of seconds are not supported here.")
|
|
||||||
return value / 1000
|
|
||||||
|
|
||||||
|
|
||||||
time_period = vol.All(vol.Any(time_period_str_colon, time_period_str_unit, timedelta,
|
def time_period_in_seconds(value):
|
||||||
time_period_dict),
|
if value.microseconds is not None and value.microseconds != 0:
|
||||||
time_period_to_milliseconds)
|
raise vol.Invalid("Maximum precision is seconds")
|
||||||
positive_time_period = vol.All(time_period, vol.Range(min=0))
|
if value.milliseconds is not None and value.milliseconds != 0:
|
||||||
positive_not_null_time_period = vol.All(time_period, vol.Range(min=0, min_included=False))
|
raise vol.Invalid("Maximum precision is seconds")
|
||||||
|
return TimePeriodSeconds(**value.as_dict())
|
||||||
|
|
||||||
|
|
||||||
|
time_period = vol.Any(time_period_str_unit, time_period_str_colon, time_period_dict)
|
||||||
|
positive_time_period = vol.All(time_period, vol.Range(min=TimePeriod()))
|
||||||
|
positive_time_period_milliseconds = vol.All(positive_time_period, time_period_in_milliseconds)
|
||||||
|
positive_time_period_seconds = vol.All(positive_time_period, time_period_in_seconds)
|
||||||
|
positive_time_period_microseconds = vol.All(positive_time_period, time_period_in_microseconds)
|
||||||
|
positive_not_null_time_period = vol.All(time_period,
|
||||||
|
vol.Range(min=TimePeriod(), min_included=False))
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
'': 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def frequency(value):
|
def frequency(value):
|
||||||
value = string(value).replace(' ', '').lower()
|
match = re.match(r"^([-+]?[0-9]*\.?[0-9]*)\s*(\w*?)(?:Hz|HZ|hz)?$", value)
|
||||||
if value.endswith('Hz') or value.endswith('hz') or value.endswith('HZ'):
|
|
||||||
value = value[:-2]
|
if match is None:
|
||||||
if not value:
|
raise vol.Invalid(u"Expected frequency with unit, "
|
||||||
raise vol.Invalid(u"Frequency must have value")
|
u"got {}".format(value))
|
||||||
multiplier = 1
|
|
||||||
if value[:-1] in METRIC_SUFFIXES:
|
mantissa = float(match.group(1))
|
||||||
multiplier = METRIC_SUFFIXES[value[:-1]]
|
if match.group(2) not in METRIC_SUFFIXES:
|
||||||
value = value[:-1]
|
raise vol.Invalid(u"Invalid frequency suffix {}".format(match.group(2)))
|
||||||
elif len(value) >= 2 and value[:-2] in METRIC_SUFFIXES:
|
|
||||||
multiplier = METRIC_SUFFIXES[value[:-2]]
|
multiplier = METRIC_SUFFIXES[match.group(2)]
|
||||||
value = value[:-2]
|
return mantissa * multiplier
|
||||||
float_val = vol.Coerce(float)(value)
|
|
||||||
return float_val * multiplier
|
|
||||||
|
|
||||||
|
|
||||||
def hostname(value):
|
def hostname(value):
|
||||||
|
@ -407,8 +430,10 @@ hex_uint32_t = vol.All(hex_int, vol.Range(min=0, max=4294967295))
|
||||||
i2c_address = hex_uint8_t
|
i2c_address = hex_uint8_t
|
||||||
|
|
||||||
|
|
||||||
def invalid(_):
|
def invalid(message):
|
||||||
raise vol.Invalid("This shouldn't happen.")
|
def validator(value):
|
||||||
|
raise vol.Invalid(message)
|
||||||
|
return validator
|
||||||
|
|
||||||
|
|
||||||
def valid(value):
|
def valid(value):
|
||||||
|
|
|
@ -135,7 +135,7 @@ CONF_SONY = 'sony'
|
||||||
CONF_PANASONIC = 'panasonic'
|
CONF_PANASONIC = 'panasonic'
|
||||||
CONF_REPEAT = 'repeat'
|
CONF_REPEAT = 'repeat'
|
||||||
CONF_TIMES = 'times'
|
CONF_TIMES = 'times'
|
||||||
CONF_WAIT_TIME_US = 'wait_time_us'
|
CONF_WAIT_TIME = 'wait_time'
|
||||||
CONF_OSCILLATION_OUTPUT = 'oscillation_output'
|
CONF_OSCILLATION_OUTPUT = 'oscillation_output'
|
||||||
CONF_SPEED = 'speed'
|
CONF_SPEED = 'speed'
|
||||||
CONF_OSCILLATION_STATE_TOPIC = 'oscillation_state_topic'
|
CONF_OSCILLATION_STATE_TOPIC = 'oscillation_state_topic'
|
||||||
|
@ -161,9 +161,29 @@ CONF_AP = 'ap'
|
||||||
CONF_CSS_URL = 'css_url'
|
CONF_CSS_URL = 'css_url'
|
||||||
CONF_JS_URL = 'js_url'
|
CONF_JS_URL = 'js_url'
|
||||||
CONF_SSL_FINGERPRINTS = 'ssl_fingerprints'
|
CONF_SSL_FINGERPRINTS = 'ssl_fingerprints'
|
||||||
|
CONF_PCF8574 = 'pcf8574'
|
||||||
CONF_PCF8575 = 'pcf8575'
|
CONF_PCF8575 = 'pcf8575'
|
||||||
CONF_SCAN = 'scan'
|
CONF_SCAN = 'scan'
|
||||||
CONF_KEEPALIVE = 'keepalive'
|
CONF_KEEPALIVE = 'keepalive'
|
||||||
|
CONF_INTEGRATION_TIME = 'integration_time'
|
||||||
|
CONF_RECEIVE_TIMEOUT = 'receive_timeout'
|
||||||
|
CONF_SCAN_INTERVAL = 'scan_interval'
|
||||||
|
CONF_MAC_ADDRESS = 'mac_address'
|
||||||
|
CONF_SETUP_MODE = 'setup_mode'
|
||||||
|
CONF_IIR_FILTER = 'iir_filter'
|
||||||
|
CONF_MEASUREMENT_DURATION = 'measurement_duration'
|
||||||
|
CONF_LOW_VOLTAGE_REFERENCE = 'low_voltage_reference'
|
||||||
|
CONF_HIGH_VOLTAGE_REFERENCE = 'high_voltage_reference'
|
||||||
|
CONF_VOLTAGE_ATTENUATION = 'voltage_attenuation'
|
||||||
|
CONF_THRESHOLD = 'threshold'
|
||||||
|
CONF_OVERSAMPLING = 'oversampling'
|
||||||
|
CONF_GAS_RESISTANCE = 'gas_resistance'
|
||||||
|
CONF_NUM_LEDS = 'num_leds'
|
||||||
|
CONF_MAX_REFRESH_RATE = 'max_refresh_rate'
|
||||||
|
CONF_CHIPSET = 'chipset'
|
||||||
|
CONF_DATA_PIN = 'data_pin'
|
||||||
|
CONF_CLOCK_PIN = 'clock_pin'
|
||||||
|
CONF_RGB_ORDER = 'rgb_order'
|
||||||
|
|
||||||
ESP32_BOARDS = [
|
ESP32_BOARDS = [
|
||||||
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',
|
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import math
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
class ESPHomeYAMLError(Exception):
|
class ESPHomeYAMLError(Exception):
|
||||||
"""General esphomeyaml exception occurred."""
|
"""General esphomeyaml exception occurred."""
|
||||||
pass
|
pass
|
||||||
|
@ -18,6 +22,155 @@ class IPAddress(object):
|
||||||
return '.'.join(str(x) for x in self.args)
|
return '.'.join(str(x) for x in self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class MACAddress(object):
|
||||||
|
def __init__(self, *parts):
|
||||||
|
if len(parts) != 6:
|
||||||
|
raise ValueError(u"MAC Address must consist of 6 items")
|
||||||
|
self.parts = parts
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ':'.join('{:02X}'.format(part) for part in self.parts)
|
||||||
|
|
||||||
|
|
||||||
|
def is_approximately_integer(value):
|
||||||
|
if isinstance(value, (int, long)):
|
||||||
|
return True
|
||||||
|
return abs(value - round(value)) < 0.001
|
||||||
|
|
||||||
|
|
||||||
|
class TimePeriod(object):
|
||||||
|
def __init__(self, microseconds=None, milliseconds=None, seconds=None,
|
||||||
|
minutes=None, hours=None, days=None):
|
||||||
|
if days is not None:
|
||||||
|
if not is_approximately_integer(days):
|
||||||
|
frac_days, days = math.modf(days)
|
||||||
|
hours = (hours or 0) + frac_days * 24
|
||||||
|
self.days = int(round(days))
|
||||||
|
else:
|
||||||
|
self.days = None
|
||||||
|
|
||||||
|
if hours is not None:
|
||||||
|
if not is_approximately_integer(hours):
|
||||||
|
frac_hours, hours = math.modf(hours)
|
||||||
|
minutes = (minutes or 0) + frac_hours * 60
|
||||||
|
self.hours = int(round(hours))
|
||||||
|
else:
|
||||||
|
self.hours = None
|
||||||
|
|
||||||
|
if minutes is not None:
|
||||||
|
if not is_approximately_integer(minutes):
|
||||||
|
frac_minutes, minutes = math.modf(minutes)
|
||||||
|
seconds = (seconds or 0) + frac_minutes * 60
|
||||||
|
self.minutes = int(round(minutes))
|
||||||
|
else:
|
||||||
|
self.minutes = None
|
||||||
|
|
||||||
|
if seconds is not None:
|
||||||
|
if not is_approximately_integer(seconds):
|
||||||
|
frac_seconds, seconds = math.modf(seconds)
|
||||||
|
milliseconds = (milliseconds or 0) + frac_seconds * 1000
|
||||||
|
self.seconds = int(round(seconds))
|
||||||
|
else:
|
||||||
|
self.seconds = None
|
||||||
|
|
||||||
|
if milliseconds is not None:
|
||||||
|
if not is_approximately_integer(milliseconds):
|
||||||
|
frac_milliseconds, milliseconds = math.modf(milliseconds)
|
||||||
|
microseconds = (microseconds or 0) + frac_milliseconds * 1000
|
||||||
|
self.milliseconds = int(round(milliseconds))
|
||||||
|
else:
|
||||||
|
self.milliseconds = None
|
||||||
|
|
||||||
|
if microseconds is not None:
|
||||||
|
if not is_approximately_integer(microseconds):
|
||||||
|
raise ValueError("Maximum precision is microseconds")
|
||||||
|
self.microseconds = int(round(microseconds))
|
||||||
|
else:
|
||||||
|
self.microseconds = None
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
out = OrderedDict()
|
||||||
|
if self.microseconds is not None:
|
||||||
|
out['microseconds'] = self.microseconds
|
||||||
|
if self.milliseconds is not None:
|
||||||
|
out['milliseconds'] = self.milliseconds
|
||||||
|
if self.seconds is not None:
|
||||||
|
out['seconds'] = self.seconds
|
||||||
|
if self.minutes is not None:
|
||||||
|
out['minutes'] = self.minutes
|
||||||
|
if self.hours is not None:
|
||||||
|
out['hours'] = self.hours
|
||||||
|
if self.days is not None:
|
||||||
|
out['days'] = self.days
|
||||||
|
return out
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_microseconds(self):
|
||||||
|
return self.total_milliseconds * 1000 + (self.microseconds or 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_milliseconds(self):
|
||||||
|
return self.total_seconds * 1000 + (self.milliseconds or 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_seconds(self):
|
||||||
|
return self.total_minutes * 60 + (self.seconds or 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_minutes(self):
|
||||||
|
return self.total_hours * 60 + (self.minutes or 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_hours(self):
|
||||||
|
return self.total_days * 24 + (self.hours or 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_days(self):
|
||||||
|
return self.days or 0
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if not isinstance(other, TimePeriod):
|
||||||
|
raise ValueError("other must be TimePeriod")
|
||||||
|
return self.total_microseconds == other.total_microseconds
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
if not isinstance(other, TimePeriod):
|
||||||
|
raise ValueError("other must be TimePeriod")
|
||||||
|
return self.total_microseconds != other.total_microseconds
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if not isinstance(other, TimePeriod):
|
||||||
|
raise ValueError("other must be TimePeriod")
|
||||||
|
return self.total_microseconds < other.total_microseconds
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if not isinstance(other, TimePeriod):
|
||||||
|
raise ValueError("other must be TimePeriod")
|
||||||
|
return self.total_microseconds > other.total_microseconds
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if not isinstance(other, TimePeriod):
|
||||||
|
raise ValueError("other must be TimePeriod")
|
||||||
|
return self.total_microseconds <= other.total_microseconds
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
if not isinstance(other, TimePeriod):
|
||||||
|
raise ValueError("other must be TimePeriod")
|
||||||
|
return self.total_microseconds >= other.total_microseconds
|
||||||
|
|
||||||
|
|
||||||
|
class TimePeriodMicroseconds(TimePeriod):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TimePeriodMilliseconds(TimePeriod):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TimePeriodSeconds(TimePeriod):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
CONFIG_PATH = None
|
CONFIG_PATH = None
|
||||||
SIMPLIFY = True
|
SIMPLIFY = True
|
||||||
ESP_PLATFORM = ''
|
ESP_PLATFORM = ''
|
||||||
|
|
|
@ -8,8 +8,9 @@ from esphomeyaml import core
|
||||||
from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \
|
from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \
|
||||||
CONF_INVERTED, \
|
CONF_INVERTED, \
|
||||||
CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_RETAIN, \
|
CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_RETAIN, \
|
||||||
CONF_STATE_TOPIC, CONF_TOPIC
|
CONF_STATE_TOPIC, CONF_TOPIC, CONF_PCF8574
|
||||||
from esphomeyaml.core import ESPHomeYAMLError, HexInt
|
from esphomeyaml.core import ESPHomeYAMLError, HexInt, TimePeriodMicroseconds, \
|
||||||
|
TimePeriodMilliseconds, TimePeriodSeconds
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -103,14 +104,32 @@ class ExpressionList(Expression):
|
||||||
return indent_all_but_first_and_last(text)
|
return indent_all_but_first_and_last(text)
|
||||||
|
|
||||||
|
|
||||||
class CallExpression(Expression):
|
class TemplateArguments(Expression):
|
||||||
def __init__(self, base, *args):
|
def __init__(self, *args):
|
||||||
super(CallExpression, self).__init__()
|
super(TemplateArguments, self).__init__()
|
||||||
self.base = base
|
|
||||||
self.args = ExpressionList(*args)
|
self.args = ExpressionList(*args)
|
||||||
self.requires.append(self.args)
|
self.requires.append(self.args)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
return u'<{}>'.format(self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class CallExpression(Expression):
|
||||||
|
def __init__(self, base, *args):
|
||||||
|
super(CallExpression, self).__init__()
|
||||||
|
self.base = base
|
||||||
|
if args and isinstance(args[0], TemplateArguments):
|
||||||
|
self.template_args = args[0]
|
||||||
|
self.requires.append(self.template_args)
|
||||||
|
args = args[1:]
|
||||||
|
else:
|
||||||
|
self.template_args = None
|
||||||
|
self.args = ExpressionList(*args)
|
||||||
|
self.requires.append(self.args)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.template_args is not None:
|
||||||
|
return u'{}{}({})'.format(self.base, self.template_args, self.args)
|
||||||
return u'{}({})'.format(self.base, self.args)
|
return u'{}({})'.format(self.base, self.args)
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,10 +237,18 @@ def safe_exp(obj):
|
||||||
return BoolLiteral(obj)
|
return BoolLiteral(obj)
|
||||||
elif isinstance(obj, (str, unicode)):
|
elif isinstance(obj, (str, unicode)):
|
||||||
return StringLiteral(obj)
|
return StringLiteral(obj)
|
||||||
|
elif isinstance(obj, HexInt):
|
||||||
|
return HexIntLiteral(obj)
|
||||||
elif isinstance(obj, (int, long)):
|
elif isinstance(obj, (int, long)):
|
||||||
return IntLiteral(obj)
|
return IntLiteral(obj)
|
||||||
elif isinstance(obj, float):
|
elif isinstance(obj, float):
|
||||||
return FloatLiteral(obj)
|
return FloatLiteral(obj)
|
||||||
|
elif isinstance(obj, TimePeriodMicroseconds):
|
||||||
|
return IntLiteral(int(obj.total_microseconds))
|
||||||
|
elif isinstance(obj, TimePeriodMilliseconds):
|
||||||
|
return IntLiteral(int(obj.total_milliseconds))
|
||||||
|
elif isinstance(obj, TimePeriodSeconds):
|
||||||
|
return IntLiteral(int(obj.total_seconds))
|
||||||
raise ValueError(u"Object is not an expression", obj)
|
raise ValueError(u"Object is not an expression", obj)
|
||||||
|
|
||||||
|
|
||||||
|
@ -300,7 +327,8 @@ def get_variable(id, type=None):
|
||||||
return None
|
return None
|
||||||
if result is None:
|
if result is None:
|
||||||
if id is not None:
|
if id is not None:
|
||||||
result = _VARIABLES[id][0]
|
if id in _VARIABLES:
|
||||||
|
result = _VARIABLES[id][0]
|
||||||
elif type is not None:
|
elif type is not None:
|
||||||
result = next((x[0] for x in _VARIABLES.itervalues() if x[1] == type), None)
|
result = next((x[0] for x in _VARIABLES.itervalues() if x[1] == type), None)
|
||||||
|
|
||||||
|
@ -371,8 +399,8 @@ def exp_gpio_pin_(obj, conf, default_mode):
|
||||||
if isinstance(conf, int):
|
if isinstance(conf, int):
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
if 'pcf8574' in conf:
|
if CONF_PCF8574 in conf:
|
||||||
hub = get_variable(conf['pcf8574'])
|
hub = get_variable(conf[CONF_PCF8574], 'io::PCF8574Component')
|
||||||
if default_mode == u'INPUT':
|
if default_mode == u'INPUT':
|
||||||
return hub.make_input_pin(conf[CONF_NUMBER],
|
return hub.make_input_pin(conf[CONF_NUMBER],
|
||||||
RawExpression('PCF8574_' + conf[CONF_MODE]),
|
RawExpression('PCF8574_' + conf[CONF_MODE]),
|
||||||
|
|
|
@ -4,8 +4,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 ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_NUMBER, CONF_MODE, \
|
from esphomeyaml.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, \
|
||||||
CONF_INVERTED, CONF_ID, CONF_PCF8575
|
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ def _translate_pin(value):
|
||||||
raise vol.Invalid(u"Invalid ESP platform.")
|
raise vol.Invalid(u"Invalid ESP platform.")
|
||||||
|
|
||||||
|
|
||||||
def _validate_gpio_pin(value):
|
def validate_gpio_pin(value):
|
||||||
value = _translate_pin(value)
|
value = _translate_pin(value)
|
||||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
if value < 0 or value > 39:
|
if value < 0 or value > 39:
|
||||||
|
@ -119,7 +119,7 @@ def _validate_gpio_pin(value):
|
||||||
|
|
||||||
|
|
||||||
def input_pin(value):
|
def input_pin(value):
|
||||||
value = _validate_gpio_pin(value)
|
value = validate_gpio_pin(value)
|
||||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
return value
|
return value
|
||||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||||
|
@ -128,7 +128,7 @@ def input_pin(value):
|
||||||
|
|
||||||
|
|
||||||
def output_pin(value):
|
def output_pin(value):
|
||||||
value = _validate_gpio_pin(value)
|
value = validate_gpio_pin(value)
|
||||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
if 34 <= value <= 39:
|
if 34 <= value <= 39:
|
||||||
raise vol.Invalid(u"ESP32: Pin {} (34-39) can only be used as "
|
raise vol.Invalid(u"ESP32: Pin {} (34-39) can only be used as "
|
||||||
|
@ -142,7 +142,7 @@ def output_pin(value):
|
||||||
|
|
||||||
|
|
||||||
def analog_pin(value):
|
def analog_pin(value):
|
||||||
value = _validate_gpio_pin(value)
|
value = validate_gpio_pin(value)
|
||||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
if 32 <= value <= 39: # ADC1
|
if 32 <= value <= 39: # ADC1
|
||||||
return value
|
return value
|
||||||
|
@ -179,57 +179,23 @@ def pin_mode(value):
|
||||||
raise vol.Invalid(u"Invalid ESP platform.")
|
raise vol.Invalid(u"Invalid ESP platform.")
|
||||||
|
|
||||||
|
|
||||||
def pcf8574_pin(value, default_mode):
|
PCF8574_OUTPUT_PIN_SCHEMA = vol.Schema({
|
||||||
if 'pcf8574' not in core.RAW_CONFIG:
|
vol.Required(CONF_PCF8574): cv.variable_id,
|
||||||
raise vol.Invalid("PCF8574 not loaded, ignore this.")
|
vol.Required(CONF_NUMBER): vol.Coerce(int),
|
||||||
|
vol.Optional(CONF_INVERTED): cv.boolean,
|
||||||
|
})
|
||||||
|
|
||||||
if isinstance(value, (str, unicode)):
|
PCF8574_INPUT_PIN_SCHEMA = PCF8574_OUTPUT_PIN_SCHEMA.extend({
|
||||||
value = {CONF_NUMBER: value}
|
vol.Optional(CONF_MODE, default='INPUT'): vol.All(vol.Upper, vol.Any("INPUT", "INPUT_PULLUP")),
|
||||||
|
})
|
||||||
|
|
||||||
if not isinstance(value, dict) or not isinstance(value.get(CONF_NUMBER), (str, unicode)) or \
|
GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, PCF8574_OUTPUT_PIN_SCHEMA, vol.Schema({
|
||||||
value[CONF_NUMBER].count('.') != 1:
|
|
||||||
raise vol.Invalid("Not PCF8574 pin")
|
|
||||||
|
|
||||||
pcf_id, pin = value[CONF_NUMBER].split('.')
|
|
||||||
pin = vol.Coerce(int)(pin)
|
|
||||||
|
|
||||||
pcf_conf = cv.ensure_list(core.RAW_CONFIG['pcf8574'])
|
|
||||||
pcf = next((conf for conf in pcf_conf if conf[CONF_ID] == pcf_id), None)
|
|
||||||
if pcf is None:
|
|
||||||
raise vol.Invalid("Unknown PCF8574 id: {}".format(pcf_id))
|
|
||||||
|
|
||||||
if pcf.get(CONF_PCF8575, False):
|
|
||||||
pin = vol.Range(min=0, max=15)(pin)
|
|
||||||
else:
|
|
||||||
pin = vol.Range(min=0, max=7)(pin)
|
|
||||||
|
|
||||||
mode = vol.All(vol.Coerce(str), vol.Upper)(value.get(CONF_MODE, default_mode))
|
|
||||||
if mode not in ['INPUT', 'INPUT_PULLUP', 'OUTPUT']:
|
|
||||||
raise vol.Invalid("Invalid pin mode for PCF8575: {}".format(mode))
|
|
||||||
|
|
||||||
return {
|
|
||||||
'pcf8574': pcf[CONF_ID],
|
|
||||||
CONF_NUMBER: pin,
|
|
||||||
CONF_INVERTED: value.get(CONF_INVERTED, False),
|
|
||||||
CONF_MODE: mode
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def pcf8574_output_pin(value):
|
|
||||||
return pcf8574_pin(value, 'OUTPUT')
|
|
||||||
|
|
||||||
|
|
||||||
def pcf8574_input_pin(value):
|
|
||||||
return pcf8574_pin(value, 'INPUT')
|
|
||||||
|
|
||||||
|
|
||||||
GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, pcf8574_output_pin, vol.Schema({
|
|
||||||
vol.Required(CONF_NUMBER): output_pin,
|
vol.Required(CONF_NUMBER): output_pin,
|
||||||
vol.Optional(CONF_MODE): pin_mode,
|
vol.Optional(CONF_MODE): pin_mode,
|
||||||
vol.Optional(CONF_INVERTED): cv.boolean,
|
vol.Optional(CONF_INVERTED): cv.boolean,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, pcf8574_input_pin, vol.Schema({
|
GPIO_INPUT_PIN_SCHEMA = vol.Any(input_pin, PCF8574_INPUT_PIN_SCHEMA, vol.Schema({
|
||||||
vol.Required(CONF_NUMBER): input_pin,
|
vol.Required(CONF_NUMBER): input_pin,
|
||||||
vol.Optional(CONF_MODE): pin_mode,
|
vol.Optional(CONF_MODE): pin_mode,
|
||||||
vol.Optional(CONF_INVERTED): cv.boolean,
|
vol.Optional(CONF_INVERTED): cv.boolean,
|
||||||
|
|
|
@ -96,6 +96,7 @@ def get_ini_content(config):
|
||||||
build_flags |= get_build_flags(config, 'BUILD_FLAGS')
|
build_flags |= get_build_flags(config, 'BUILD_FLAGS')
|
||||||
build_flags.add(u"-DESPHOMEYAML_USE")
|
build_flags.add(u"-DESPHOMEYAML_USE")
|
||||||
build_flags |= get_build_flags(config, 'required_build_flags')
|
build_flags |= get_build_flags(config, 'required_build_flags')
|
||||||
|
build_flags |= get_build_flags(config, 'REQUIRED_BUILD_FLAGS')
|
||||||
|
|
||||||
# avoid changing build flags order
|
# avoid changing build flags order
|
||||||
build_flags = sorted(list(build_flags))
|
build_flags = sorted(list(build_flags))
|
||||||
|
@ -104,27 +105,16 @@ def get_ini_content(config):
|
||||||
|
|
||||||
lib_deps = set()
|
lib_deps = set()
|
||||||
lib_deps.add(config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI])
|
lib_deps.add(config[CONF_ESPHOMEYAML][CONF_LIBRARY_URI])
|
||||||
|
lib_deps |= get_build_flags(config, 'LIB_DEPS')
|
||||||
|
lib_deps |= get_build_flags(config, 'lib_deps')
|
||||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||||
lib_deps |= {
|
lib_deps |= {
|
||||||
'ArduinoOTA',
|
'Preferences', # Preferences helper
|
||||||
'Update',
|
|
||||||
'ESPmDNS',
|
|
||||||
'Wire',
|
|
||||||
'FS',
|
|
||||||
'Preferences',
|
|
||||||
|
|
||||||
}
|
}
|
||||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
# avoid changing build flags order
|
||||||
lib_deps |= {
|
lib_deps = sorted(x for x in lib_deps if x)
|
||||||
'ESP8266WiFi',
|
if lib_deps:
|
||||||
'Wire',
|
options[u'lib_deps'] = u'\n '.join(lib_deps)
|
||||||
'Hash',
|
|
||||||
'ESP8266mDNS',
|
|
||||||
'ArduinoOTA',
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
raise ESPHomeYAMLError("Unsupported platform {}".format(core.ESP_PLATFORM))
|
|
||||||
options[u'lib_deps'] = u'\n '.join(sorted(list(lib_deps)))
|
|
||||||
|
|
||||||
return INI_CONTENT_FORMAT.format(**options)
|
return INI_CONTENT_FORMAT.format(**options)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ from collections import OrderedDict
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress
|
from esphomeyaml.core import ESPHomeYAMLError, HexInt, IPAddress, MACAddress, TimePeriod, \
|
||||||
|
TimePeriodMicroseconds, TimePeriodMilliseconds, TimePeriodSeconds
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -245,11 +246,30 @@ def hex_int_representer(_, data):
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
def ipaddress_representer(_, data):
|
def stringify_representer(_, data):
|
||||||
node = yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=str(data))
|
node = yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=str(data))
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
TIME_PERIOD_UNIT_MAP = {
|
||||||
|
'microseconds': 'us',
|
||||||
|
'milliseconds': 'ms',
|
||||||
|
'seconds': 's',
|
||||||
|
'minutes': 'min',
|
||||||
|
'hours': 'h',
|
||||||
|
'days': 'd',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def represent_time_period(dumper, data):
|
||||||
|
dictionary = data.as_dict()
|
||||||
|
if len(dictionary) == 1:
|
||||||
|
unit, value = dictionary.popitem()
|
||||||
|
out = '{}{}'.format(value, TIME_PERIOD_UNIT_MAP[unit])
|
||||||
|
return yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=out)
|
||||||
|
return represent_odict(dumper, 'tag:yaml.org,2002:map', dictionary)
|
||||||
|
|
||||||
|
|
||||||
yaml.SafeDumper.add_representer(
|
yaml.SafeDumper.add_representer(
|
||||||
OrderedDict,
|
OrderedDict,
|
||||||
lambda dumper, value:
|
lambda dumper, value:
|
||||||
|
@ -264,4 +284,9 @@ yaml.SafeDumper.add_representer(
|
||||||
|
|
||||||
yaml.SafeDumper.add_representer(unicode, unicode_representer)
|
yaml.SafeDumper.add_representer(unicode, unicode_representer)
|
||||||
yaml.SafeDumper.add_representer(HexInt, hex_int_representer)
|
yaml.SafeDumper.add_representer(HexInt, hex_int_representer)
|
||||||
yaml.SafeDumper.add_representer(IPAddress, ipaddress_representer)
|
yaml.SafeDumper.add_representer(IPAddress, stringify_representer)
|
||||||
|
yaml.SafeDumper.add_representer(MACAddress, stringify_representer)
|
||||||
|
yaml.SafeDumper.add_representer(TimePeriod, represent_time_period)
|
||||||
|
yaml.SafeDumper.add_representer(TimePeriodMicroseconds, represent_time_period)
|
||||||
|
yaml.SafeDumper.add_representer(TimePeriodMilliseconds, represent_time_period)
|
||||||
|
yaml.SafeDumper.add_representer(TimePeriodSeconds, represent_time_period)
|
||||||
|
|
Loading…
Reference in a new issue