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 && \
|
||||
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 . .
|
||||
RUN pip install -e .
|
||||
|
||||
|
|
|
@ -156,6 +156,10 @@ def upload_program(config, args, port):
|
|||
return run_platformio('platformio', 'run', '-d', get_base_path(config),
|
||||
'-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]:
|
||||
host = str(config[CONF_WIFI][CONF_MANUAL_IP][CONF_STATIC_IP])
|
||||
elif CONF_HOSTNAME in config[CONF_WIFI]:
|
||||
|
|
|
@ -2,27 +2,19 @@ import voluptuous as vol
|
|||
|
||||
import esphomeyaml.config_validation as cv
|
||||
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']
|
||||
|
||||
ADS1115_COMPONENT_CLASS = 'sensor::ADS1115Component'
|
||||
|
||||
RATES = {
|
||||
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',
|
||||
}
|
||||
RATE_REMOVE_MESSAGE = """The rate option has been removed in 1.5.0 and is no longer required."""
|
||||
|
||||
ADS1115_SCHEMA = vol.Schema({
|
||||
cv.GenerateID('ads1115'): cv.register_variable_id,
|
||||
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])
|
||||
|
@ -30,11 +22,8 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
|
|||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
address = HexIntLiteral(conf[CONF_ADDRESS])
|
||||
rhs = App.make_ads1115_component(address)
|
||||
ads1115 = Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
||||
if CONF_RATE in conf:
|
||||
add(ads1115.set_rate(RawExpression(RATES[conf[CONF_RATE]])))
|
||||
rhs = App.make_ads1115_component(conf[CONF_ADDRESS])
|
||||
Pvariable(ADS1115_COMPONENT_CLASS, conf[CONF_ID], rhs)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED
|
||||
from esphomeyaml.helpers import add, setup_mqtt_component
|
||||
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_INVERTED, CONF_MQTT_ID
|
||||
from esphomeyaml.helpers import add, setup_mqtt_component, App, Pvariable
|
||||
|
||||
DEVICE_CLASSES = [
|
||||
'', '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):
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
|
@ -35,4 +39,11 @@ def setup_mqtt_binary_sensor(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'
|
||||
|
|
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({
|
||||
cv.GenerateID('dallas'): cv.register_variable_id,
|
||||
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({
|
||||
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,
|
||||
pins.schema_validate_number(validate_pin_number)),
|
||||
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
|
||||
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
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID('i2c'): cv.register_variable_id,
|
||||
vol.Required(CONF_SDA, default='SDA'): 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,
|
||||
})
|
||||
|
||||
|
@ -19,6 +21,10 @@ def to_code(config):
|
|||
i2c = Pvariable('I2CComponent', config[CONF_ID], rhs)
|
||||
if CONF_FREQUENCY in config:
|
||||
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'
|
||||
|
||||
LIB_DEPS = 'Wire'
|
||||
|
|
|
@ -2,17 +2,16 @@ import voluptuous as vol
|
|||
|
||||
import esphomeyaml.config_validation as cv
|
||||
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
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
IR_TRANSMITTER_COMPONENT_CLASS = 'switch_::IRTransmitterComponent'
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||
cv.GenerateID('ir_transmitter'): cv.register_variable_id,
|
||||
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
|
||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH
|
||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT
|
||||
from esphomeyaml.helpers import add
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
@ -10,6 +10,8 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
|||
def setup_light_component(obj, config):
|
||||
if CONF_DEFAULT_TRANSITION_LENGTH in config:
|
||||
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'
|
||||
|
|
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.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_ID, \
|
||||
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({
|
||||
cv.GenerateID('monochromatic_light'): cv.register_variable_id,
|
||||
vol.Required(CONF_OUTPUT): cv.variable_id,
|
||||
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])
|
||||
rhs = App.make_monochromatic_light(config[CONF_NAME], output)
|
||||
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)
|
||||
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_BLUE): cv.variable_id,
|
||||
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])
|
||||
rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue)
|
||||
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)
|
||||
light.setup_light_component(light_struct.Pstate, config)
|
||||
|
|
|
@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv
|
|||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||
CONF_GREEN, CONF_ID, CONF_NAME, CONF_RED, CONF_WHITE
|
||||
from esphomeyaml.helpers import App, add, get_variable, setup_mqtt_component, variable
|
||||
from esphomeyaml.helpers import App, get_variable, setup_mqtt_component, variable
|
||||
|
||||
PLATFORM_SCHEMA = light.PLATFORM_SCHEMA.extend({
|
||||
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_WHITE): cv.variable_id,
|
||||
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])
|
||||
rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white)
|
||||
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)
|
||||
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.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
|
||||
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_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266,
|
||||
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'
|
||||
|
||||
|
||||
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'
|
||||
|
||||
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({
|
||||
cv.GenerateID('pca9685'): cv.register_variable_id,
|
||||
vol.Required(CONF_FREQUENCY): vol.All(cv.frequency,
|
||||
vol.Range(min=24, max=1526)),
|
||||
vol.Optional(CONF_PHASE_BALANCER): vol.All(vol.Title, vol.Any(*PHASE_BALANCERS)),
|
||||
vol.Range(min=23.84, max=1525.88)),
|
||||
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])
|
||||
|
|
|
@ -7,8 +7,8 @@ from esphomeyaml.helpers import App, Pvariable, add, exp_gpio_output_pin
|
|||
|
||||
POWER_SUPPLY_SCHEMA = cv.REQUIRED_ID_SCHEMA.extend({
|
||||
vol.Required(CONF_PIN): pins.GPIO_OUTPUT_PIN_SCHEMA,
|
||||
vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period,
|
||||
vol.Optional(CONF_KEEP_ON_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_milliseconds,
|
||||
})
|
||||
|
||||
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_ICON): cv.icon,
|
||||
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
|
||||
})
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
|||
cv.GenerateID('adc'): cv.register_variable_id,
|
||||
vol.Required(CONF_PIN): pins.analog_pin,
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -9,23 +9,23 @@ from esphomeyaml.helpers import RawExpression, get_variable, Pvariable
|
|||
DEPENDENCIES = ['ads1115']
|
||||
|
||||
MUX = {
|
||||
'A0_A1': 'ADS1115_MUX_P0_N1',
|
||||
'A0_A3': 'ADS1115_MUX_P0_N3',
|
||||
'A1_A3': 'ADS1115_MUX_P1_N3',
|
||||
'A2_A3': 'ADS1115_MUX_P2_N3',
|
||||
'A0_GND': 'ADS1115_MUX_P0_NG',
|
||||
'A1_GND': 'ADS1115_MUX_P1_NG',
|
||||
'A2_GND': 'ADS1115_MUX_P2_NG',
|
||||
'A3_GND': 'ADS1115_MUX_P3_NG',
|
||||
'A0_A1': 'sensor::ADS1115_MULTIPLEXER_P0_N1',
|
||||
'A0_A3': 'sensor::ADS1115_MULTIPLEXER_P0_N3',
|
||||
'A1_A3': 'sensor::ADS1115_MULTIPLEXER_P1_N3',
|
||||
'A2_A3': 'sensor::ADS1115_MULTIPLEXER_P2_N3',
|
||||
'A0_GND': 'sensor::ADS1115_MULTIPLEXER_P0_NG',
|
||||
'A1_GND': 'sensor::ADS1115_MULTIPLEXER_P1_NG',
|
||||
'A2_GND': 'sensor::ADS1115_MULTIPLEXER_P2_NG',
|
||||
'A3_GND': 'sensor::ADS1115_MULTIPLEXER_P3_NG',
|
||||
}
|
||||
|
||||
GAIN = {
|
||||
'6.144': 'ADS1115_PGA_6P144',
|
||||
'4.096': 'ADS1115_PGA_6P096',
|
||||
'2.048': 'ADS1115_PGA_2P048',
|
||||
'1.024': 'ADS1115_PGA_1P024',
|
||||
'0.512': 'ADS1115_PGA_0P512',
|
||||
'0.256': 'ADS1115_PGA_0P256',
|
||||
'6.144': 'sensor::ADS1115_GAIN_6P144',
|
||||
'4.096': 'sensor::ADS1115_GAIN_6P096',
|
||||
'2.048': 'sensor::ADS1115_GAIN_2P048',
|
||||
'1.024': 'sensor::ADS1115_GAIN_1P024',
|
||||
'0.512': 'sensor::ADS1115_GAIN_0P512',
|
||||
'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_GAIN): validate_gain,
|
||||
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)
|
||||
|
||||
|
||||
|
|
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_PRESSURE): MQTT_SENSOR_SCHEMA,
|
||||
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
|
||||
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,
|
||||
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
|
||||
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
|
||||
vol.Optional(CONF_DALLAS_ID): cv.variable_id,
|
||||
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):
|
||||
|
|
|
@ -1,33 +1,40 @@
|
|||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.components.sensor import MQTT_SENSOR_SCHEMA
|
||||
from esphomeyaml.const import CONF_HUMIDITY, CONF_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \
|
||||
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({
|
||||
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_HUMIDITY): MQTT_SENSOR_SCHEMA,
|
||||
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):
|
||||
pin = exp_gpio_output_pin(config[CONF_PIN])
|
||||
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][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)
|
||||
if CONF_MODEL in config:
|
||||
model = RawExpression('DHT::{}'.format(config[CONF_MODEL]))
|
||||
add(dht.Pdht.set_dht_model(model))
|
||||
constant = DHT_MODELS[config[CONF_MODEL]]
|
||||
add(dht.Pdht.set_dht_model(RawExpression(constant)))
|
||||
sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
|
||||
sensor.setup_mqtt_sensor_component(dht.Pmqtt_temperature, config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(), config[CONF_HUMIDITY])
|
||||
|
|
|
@ -13,7 +13,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
|||
cv.GenerateID('dht_sensor'): cv.register_variable_id,
|
||||
vol.Required(CONF_TEMPERATURE): 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,
|
||||
vol.Required(CONF_TEMPERATURE): 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_Z): 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.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)
|
||||
|
||||
|
||||
|
|
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_ECHO_PIN): pins.GPIO_INPUT_PIN_SCHEMA,
|
||||
vol.Exclusive(CONF_TIMEOUT_METER, 'timeout'): cv.positive_float,
|
||||
vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_int,
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_not_null_time_period,
|
||||
vol.Exclusive(CONF_TIMEOUT_TIME, 'timeout'): cv.positive_time_period_microseconds,
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
|
||||
}).extend(sensor.MQTT_SENSOR_SCHEMA.schema)
|
||||
|
||||
|
||||
|
|
|
@ -3,13 +3,20 @@ import voluptuous as vol
|
|||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import switch
|
||||
from esphomeyaml.components.ir_transmitter import IR_TRANSMITTER_COMPONENT_CLASS
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_COMMAND, CONF_DATA, CONF_IR_TRANSMITTER_ID, \
|
||||
CONF_LG, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_REPEAT, CONF_SONY, CONF_TIMES, \
|
||||
CONF_WAIT_TIME_US, CONF_RAW, CONF_CARRIER_FREQUENCY, CONF_NAME, CONF_ID
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_COMMAND, CONF_DATA, \
|
||||
CONF_ID, CONF_IR_TRANSMITTER_ID, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, \
|
||||
CONF_RAW, CONF_REPEAT, CONF_SONY, CONF_TIMES, CONF_WAIT_TIME
|
||||
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,
|
||||
vol.Exclusive(CONF_NEC, 'code'): vol.Schema({
|
||||
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.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,
|
||||
}).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
|
||||
SendData = MockObj('switch_::ir::SendData', '::')
|
||||
|
@ -77,7 +85,7 @@ def exp_send_data(config):
|
|||
wait_us = None
|
||||
else:
|
||||
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 = base.repeat(times, wait_us)
|
||||
return base
|
||||
|
|
|
@ -3,7 +3,8 @@ import logging
|
|||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_PORT, CONF_JS_URL, CONF_CSS_URL, CONF_ID
|
||||
from esphomeyaml 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
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -26,3 +27,9 @@ def to_code(config):
|
|||
|
||||
|
||||
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 esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import core
|
||||
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
|
||||
|
||||
|
||||
|
@ -87,3 +89,9 @@ def to_code(config):
|
|||
|
||||
if CONF_HOSTNAME in config:
|
||||
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.Optional(CONF_LIBRARY_URI, default=DEFAULT_LIBRARY_URI): cv.string,
|
||||
vol.Optional(CONF_SIMPLIFY, default=True): cv.boolean,
|
||||
vol.Optional(CONF_USE_BUILD_FLAGS, default=False): cv.boolean,
|
||||
vol.Optional(CONF_USE_BUILD_FLAGS, default=True): cv.boolean,
|
||||
})
|
||||
|
||||
REQUIRED_COMPONENTS = [
|
||||
|
|
|
@ -4,7 +4,6 @@ from __future__ import print_function
|
|||
|
||||
import logging
|
||||
import re
|
||||
from datetime import timedelta
|
||||
|
||||
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_PAYLOAD_NOT_AVAILABLE, CONF_PLATFORM, CONF_RETAIN, CONF_STATE_TOPIC, CONF_TOPIC, \
|
||||
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
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -178,19 +178,28 @@ def has_at_least_one_key(*keys):
|
|||
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(
|
||||
dict, vol.Schema({
|
||||
'days': vol.Coerce(int),
|
||||
'hours': vol.Coerce(int),
|
||||
'minutes': vol.Coerce(int),
|
||||
'seconds': vol.Coerce(int),
|
||||
'milliseconds': vol.Coerce(int),
|
||||
'days': vol.Coerce(float),
|
||||
'hours': vol.Coerce(float),
|
||||
'minutes': vol.Coerce(float),
|
||||
'seconds': vol.Coerce(float),
|
||||
'milliseconds': vol.Coerce(float),
|
||||
'microseconds': vol.Coerce(float),
|
||||
}),
|
||||
has_at_least_one_key('days', 'hours', 'minutes',
|
||||
'seconds', 'milliseconds'),
|
||||
lambda value: timedelta(**value))
|
||||
'seconds', 'milliseconds', 'microseconds'),
|
||||
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):
|
||||
|
@ -220,7 +229,7 @@ def time_period_str_colon(value):
|
|||
else:
|
||||
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:
|
||||
offset *= -1
|
||||
|
@ -232,10 +241,19 @@ def time_period_str_unit(value):
|
|||
"""Validate and transform time period with time unit and integer value."""
|
||||
if isinstance(value, int):
|
||||
value = str(value)
|
||||
elif not isinstance(value, str):
|
||||
elif not isinstance(value, (str, unicode)):
|
||||
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 = {
|
||||
'us': 'microseconds',
|
||||
'microseconds': 'microseconds',
|
||||
'ms': 'milliseconds',
|
||||
'milliseconds': 'milliseconds',
|
||||
's': 'seconds',
|
||||
|
@ -256,51 +274,56 @@ def time_period_str_unit(value):
|
|||
u"got {}".format(value))
|
||||
|
||||
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):
|
||||
if isinstance(value, (int, long)):
|
||||
return value
|
||||
if isinstance(value, float):
|
||||
return int(value)
|
||||
return int(value.total_seconds() * 1000)
|
||||
def time_period_in_milliseconds(value):
|
||||
if value.microseconds is not None and value.microseconds != 0:
|
||||
raise vol.Invalid("Maximum precision is milliseconds")
|
||||
return TimePeriodMilliseconds(**value.as_dict())
|
||||
|
||||
|
||||
def time_period_to_seconds(value):
|
||||
if value / 1000 != value // 1000:
|
||||
raise vol.Invalid("Fractions of seconds are not supported here.")
|
||||
return value / 1000
|
||||
def time_period_in_microseconds(value):
|
||||
return TimePeriodMicroseconds(**value.as_dict())
|
||||
|
||||
|
||||
time_period = vol.All(vol.Any(time_period_str_colon, time_period_str_unit, timedelta,
|
||||
time_period_dict),
|
||||
time_period_to_milliseconds)
|
||||
positive_time_period = vol.All(time_period, vol.Range(min=0))
|
||||
positive_not_null_time_period = vol.All(time_period, vol.Range(min=0, min_included=False))
|
||||
def time_period_in_seconds(value):
|
||||
if value.microseconds is not None and value.microseconds != 0:
|
||||
raise vol.Invalid("Maximum precision is seconds")
|
||||
if value.milliseconds is not None and value.milliseconds != 0:
|
||||
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 = {
|
||||
'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,
|
||||
'': 1
|
||||
}
|
||||
|
||||
|
||||
def frequency(value):
|
||||
value = string(value).replace(' ', '').lower()
|
||||
if value.endswith('Hz') or value.endswith('hz') or value.endswith('HZ'):
|
||||
value = value[:-2]
|
||||
if not value:
|
||||
raise vol.Invalid(u"Frequency must have value")
|
||||
multiplier = 1
|
||||
if value[:-1] in METRIC_SUFFIXES:
|
||||
multiplier = METRIC_SUFFIXES[value[:-1]]
|
||||
value = value[:-1]
|
||||
elif len(value) >= 2 and value[:-2] in METRIC_SUFFIXES:
|
||||
multiplier = METRIC_SUFFIXES[value[:-2]]
|
||||
value = value[:-2]
|
||||
float_val = vol.Coerce(float)(value)
|
||||
return float_val * multiplier
|
||||
match = re.match(r"^([-+]?[0-9]*\.?[0-9]*)\s*(\w*?)(?:Hz|HZ|hz)?$", value)
|
||||
|
||||
if match is None:
|
||||
raise vol.Invalid(u"Expected frequency with unit, "
|
||||
u"got {}".format(value))
|
||||
|
||||
mantissa = float(match.group(1))
|
||||
if match.group(2) not in METRIC_SUFFIXES:
|
||||
raise vol.Invalid(u"Invalid frequency suffix {}".format(match.group(2)))
|
||||
|
||||
multiplier = METRIC_SUFFIXES[match.group(2)]
|
||||
return mantissa * multiplier
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
def invalid(_):
|
||||
raise vol.Invalid("This shouldn't happen.")
|
||||
def invalid(message):
|
||||
def validator(value):
|
||||
raise vol.Invalid(message)
|
||||
return validator
|
||||
|
||||
|
||||
def valid(value):
|
||||
|
|
|
@ -135,7 +135,7 @@ CONF_SONY = 'sony'
|
|||
CONF_PANASONIC = 'panasonic'
|
||||
CONF_REPEAT = 'repeat'
|
||||
CONF_TIMES = 'times'
|
||||
CONF_WAIT_TIME_US = 'wait_time_us'
|
||||
CONF_WAIT_TIME = 'wait_time'
|
||||
CONF_OSCILLATION_OUTPUT = 'oscillation_output'
|
||||
CONF_SPEED = 'speed'
|
||||
CONF_OSCILLATION_STATE_TOPIC = 'oscillation_state_topic'
|
||||
|
@ -161,9 +161,29 @@ CONF_AP = 'ap'
|
|||
CONF_CSS_URL = 'css_url'
|
||||
CONF_JS_URL = 'js_url'
|
||||
CONF_SSL_FINGERPRINTS = 'ssl_fingerprints'
|
||||
CONF_PCF8574 = 'pcf8574'
|
||||
CONF_PCF8575 = 'pcf8575'
|
||||
CONF_SCAN = 'scan'
|
||||
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 = [
|
||||
'featheresp32', 'node32s', 'espea32', 'firebeetle32', 'esp32doit-devkit-v1',
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
import math
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
class ESPHomeYAMLError(Exception):
|
||||
"""General esphomeyaml exception occurred."""
|
||||
pass
|
||||
|
@ -18,6 +22,155 @@ class IPAddress(object):
|
|||
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
|
||||
SIMPLIFY = True
|
||||
ESP_PLATFORM = ''
|
||||
|
|
|
@ -8,8 +8,9 @@ from esphomeyaml import core
|
|||
from esphomeyaml.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, \
|
||||
CONF_INVERTED, \
|
||||
CONF_MODE, CONF_NUMBER, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_RETAIN, \
|
||||
CONF_STATE_TOPIC, CONF_TOPIC
|
||||
from esphomeyaml.core import ESPHomeYAMLError, HexInt
|
||||
CONF_STATE_TOPIC, CONF_TOPIC, CONF_PCF8574
|
||||
from esphomeyaml.core import ESPHomeYAMLError, HexInt, TimePeriodMicroseconds, \
|
||||
TimePeriodMilliseconds, TimePeriodSeconds
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -103,14 +104,32 @@ class ExpressionList(Expression):
|
|||
return indent_all_but_first_and_last(text)
|
||||
|
||||
|
||||
class CallExpression(Expression):
|
||||
def __init__(self, base, *args):
|
||||
super(CallExpression, self).__init__()
|
||||
self.base = base
|
||||
class TemplateArguments(Expression):
|
||||
def __init__(self, *args):
|
||||
super(TemplateArguments, self).__init__()
|
||||
self.args = ExpressionList(*args)
|
||||
self.requires.append(self.args)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
@ -218,10 +237,18 @@ def safe_exp(obj):
|
|||
return BoolLiteral(obj)
|
||||
elif isinstance(obj, (str, unicode)):
|
||||
return StringLiteral(obj)
|
||||
elif isinstance(obj, HexInt):
|
||||
return HexIntLiteral(obj)
|
||||
elif isinstance(obj, (int, long)):
|
||||
return IntLiteral(obj)
|
||||
elif isinstance(obj, float):
|
||||
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)
|
||||
|
||||
|
||||
|
@ -300,7 +327,8 @@ def get_variable(id, type=None):
|
|||
return None
|
||||
if result is None:
|
||||
if id is not None:
|
||||
result = _VARIABLES[id][0]
|
||||
if id in _VARIABLES:
|
||||
result = _VARIABLES[id][0]
|
||||
elif type is not 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):
|
||||
return conf
|
||||
|
||||
if 'pcf8574' in conf:
|
||||
hub = get_variable(conf['pcf8574'])
|
||||
if CONF_PCF8574 in conf:
|
||||
hub = get_variable(conf[CONF_PCF8574], 'io::PCF8574Component')
|
||||
if default_mode == u'INPUT':
|
||||
return hub.make_input_pin(conf[CONF_NUMBER],
|
||||
RawExpression('PCF8574_' + conf[CONF_MODE]),
|
||||
|
|
|
@ -4,8 +4,8 @@ import voluptuous as vol
|
|||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.const import ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266, CONF_NUMBER, CONF_MODE, \
|
||||
CONF_INVERTED, CONF_ID, CONF_PCF8575
|
||||
from esphomeyaml.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, \
|
||||
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -96,7 +96,7 @@ def _translate_pin(value):
|
|||
raise vol.Invalid(u"Invalid ESP platform.")
|
||||
|
||||
|
||||
def _validate_gpio_pin(value):
|
||||
def validate_gpio_pin(value):
|
||||
value = _translate_pin(value)
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if value < 0 or value > 39:
|
||||
|
@ -119,7 +119,7 @@ def _validate_gpio_pin(value):
|
|||
|
||||
|
||||
def input_pin(value):
|
||||
value = _validate_gpio_pin(value)
|
||||
value = validate_gpio_pin(value)
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
return value
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
|
@ -128,7 +128,7 @@ def input_pin(value):
|
|||
|
||||
|
||||
def output_pin(value):
|
||||
value = _validate_gpio_pin(value)
|
||||
value = validate_gpio_pin(value)
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if 34 <= value <= 39:
|
||||
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):
|
||||
value = _validate_gpio_pin(value)
|
||||
value = validate_gpio_pin(value)
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
|
||||
if 32 <= value <= 39: # ADC1
|
||||
return value
|
||||
|
@ -179,57 +179,23 @@ def pin_mode(value):
|
|||
raise vol.Invalid(u"Invalid ESP platform.")
|
||||
|
||||
|
||||
def pcf8574_pin(value, default_mode):
|
||||
if 'pcf8574' not in core.RAW_CONFIG:
|
||||
raise vol.Invalid("PCF8574 not loaded, ignore this.")
|
||||
PCF8574_OUTPUT_PIN_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_PCF8574): cv.variable_id,
|
||||
vol.Required(CONF_NUMBER): vol.Coerce(int),
|
||||
vol.Optional(CONF_INVERTED): cv.boolean,
|
||||
})
|
||||
|
||||
if isinstance(value, (str, unicode)):
|
||||
value = {CONF_NUMBER: value}
|
||||
PCF8574_INPUT_PIN_SCHEMA = PCF8574_OUTPUT_PIN_SCHEMA.extend({
|
||||
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 \
|
||||
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({
|
||||
GPIO_OUTPUT_PIN_SCHEMA = vol.Any(output_pin, PCF8574_OUTPUT_PIN_SCHEMA, vol.Schema({
|
||||
vol.Required(CONF_NUMBER): output_pin,
|
||||
vol.Optional(CONF_MODE): pin_mode,
|
||||
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.Optional(CONF_MODE): pin_mode,
|
||||
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.add(u"-DESPHOMEYAML_USE")
|
||||
build_flags |= get_build_flags(config, 'required_build_flags')
|
||||
build_flags |= get_build_flags(config, 'REQUIRED_BUILD_FLAGS')
|
||||
|
||||
# avoid changing build flags order
|
||||
build_flags = sorted(list(build_flags))
|
||||
|
@ -104,27 +105,16 @@ def get_ini_content(config):
|
|||
|
||||
lib_deps = set()
|
||||
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:
|
||||
lib_deps |= {
|
||||
'ArduinoOTA',
|
||||
'Update',
|
||||
'ESPmDNS',
|
||||
'Wire',
|
||||
'FS',
|
||||
'Preferences',
|
||||
|
||||
'Preferences', # Preferences helper
|
||||
}
|
||||
elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
|
||||
lib_deps |= {
|
||||
'ESP8266WiFi',
|
||||
'Wire',
|
||||
'Hash',
|
||||
'ESP8266mDNS',
|
||||
'ArduinoOTA',
|
||||
}
|
||||
else:
|
||||
raise ESPHomeYAMLError("Unsupported platform {}".format(core.ESP_PLATFORM))
|
||||
options[u'lib_deps'] = u'\n '.join(sorted(list(lib_deps)))
|
||||
# avoid changing build flags order
|
||||
lib_deps = sorted(x for x in lib_deps if x)
|
||||
if lib_deps:
|
||||
options[u'lib_deps'] = u'\n '.join(lib_deps)
|
||||
|
||||
return INI_CONTENT_FORMAT.format(**options)
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ from collections import OrderedDict
|
|||
|
||||
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__)
|
||||
|
||||
|
@ -245,11 +246,30 @@ def hex_int_representer(_, data):
|
|||
return node
|
||||
|
||||
|
||||
def ipaddress_representer(_, data):
|
||||
def stringify_representer(_, data):
|
||||
node = yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=str(data))
|
||||
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(
|
||||
OrderedDict,
|
||||
lambda dumper, value:
|
||||
|
@ -264,4 +284,9 @@ yaml.SafeDumper.add_representer(
|
|||
|
||||
yaml.SafeDumper.add_representer(unicode, unicode_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