1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-13 13:25:50 +00:00

Compare commits

..

20 Commits

Author SHA1 Message Date
Otto Winter
f7671f0c90 Bump version to 1.8.2 2018-10-07 17:01:15 +02:00
Otto Winter
639b97ccb2 WiFi: Add power save mode option (#150)
* WiFi: Add power save mode option

* Lint
2018-10-07 16:52:14 +02:00
Otto Winter
0374b3a0b3 Fix component loader value error (#149)
* Print better error message when loader fails with ValueError

* Improve

* Improve
2018-10-07 14:38:22 +02:00
Otto Winter
7ce753b76f Docker default to starting dashboard (#143) 2018-10-04 19:01:57 +02:00
Otto Winter
05a1089ed2 Bump platformio-espressif32 to 1.4.0 (#142) 2018-10-04 19:01:24 +02:00
Otto Winter
71947bb6ac Fix using unicode in lambdas (#141)
https://github.com/OttoWinter/esphomeyaml/issues/128#issuecomment-425777989
2018-10-04 19:01:13 +02:00
Otto Winter
ef54e33b70 Add clean MQTT button to dashboard (#139) 2018-10-04 19:01:02 +02:00
Otto Winter
12f20fc3cf Fix serial monitor opening when logger disabled (#138)
Fixes #137
2018-10-04 19:00:51 +02:00
Otto Winter
ffdcddc18e Add SSD1306 64x48 display (#136) 2018-09-29 14:50:14 +02:00
Otto Winter
85d70eb5a0 Auto-Update esphomelib dev version (#134)
* Auto-Update esphomelib dev version

* Lint
2018-09-29 14:50:04 +02:00
Otto Winter
ffb793177a Enable Travis Tests (#133) 2018-09-28 19:34:28 +02:00
Otto Winter
d3f2fab88a Fix SSD1306 lambda (#132)
As per #128
2018-09-28 18:17:22 +02:00
Otto Winter
0fa52d0ce6 Fix MQTT discovery enabled when discovery_retain in config (#131) 2018-09-27 16:34:11 +02:00
Otto Winter
cf264a2743 Fix binary sensor heartbeat not working (#130) 2018-09-27 16:34:02 +02:00
Otto Winter
433b605bef Bump version to 1.8.1 2018-09-26 19:00:41 +02:00
Otto Winter
6e60c6493a Use cache for HassIO add-on images 2018-09-26 18:59:39 +02:00
Otto Winter
4e63bc96d5 Fix main docker image missing platformio 2018-09-26 18:39:55 +02:00
Otto Winter
ce4b339d16 Split up BLE tests into new file 2018-09-26 18:39:41 +02:00
Otto Winter
ab6d293d0d Fix docker installs using old platformio version (#125)
* Fix min platformio version and update requirements

* Remove unnecessary requirements from travis
2018-09-27 01:14:51 +09:00
Otto Winter
5e5137960d Limit upload speed to 115200 (#122)
* Limit upload speed to 115200

* Lint
2018-09-26 01:27:47 +09:00
25 changed files with 389 additions and 121 deletions

View File

@@ -47,11 +47,16 @@ pylint:
script: script:
- pylint esphomeyaml - pylint esphomeyaml
test: test1:
<<: *test <<: *test
script: script:
- esphomeyaml tests/test1.yaml compile - esphomeyaml tests/test1.yaml compile
test2:
<<: *test
script:
- esphomeyaml tests/test2.yaml compile
.build-hassio: &build-hassio .build-hassio: &build-hassio
<<: *docker-builder <<: *docker-builder
stage: build stage: build
@@ -79,6 +84,10 @@ test:
- echo "Publishing version ${version}" - echo "Publishing version ${version}"
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" - docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
- docker pull "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" - docker pull "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- | - |
docker tag \ docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \ "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
@@ -87,6 +96,7 @@ test:
docker tag \ docker tag \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}" \ "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}" \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest" "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}" - docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest" - docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"

View File

@@ -2,9 +2,19 @@ sudo: false
language: python language: python
python: python:
- "2.7" - "2.7"
install: jobs:
include:
- name: "Lint"
install:
- pip install -r requirements.txt - pip install -r requirements.txt
- pip install tornado esptool flake8==3.5.0 pylint==1.8.4 tzlocal pillow - pip install flake8==3.5.0 pylint==1.9.3 tzlocal pillow
script: script:
- flake8 esphomeyaml - flake8 esphomeyaml
- pylint esphomeyaml - pylint esphomeyaml
- name: "Test"
install:
- pip install -e .
- pip install tzlocal pillow
script:
- esphomeyaml tests/test1.yaml compile
- esphomeyaml tests/test2.yaml compile

View File

@@ -10,9 +10,8 @@ EXPOSE 6123
VOLUME /config VOLUME /config
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/ RUN pip install --no-cache-dir --no-binary :all: platformio && \
RUN pip install --no-cache-dir -r requirements.txt && \ platformio settings set enable_telemetry No
pip install --no-cache-dir tornado esptool
COPY docker/platformio.ini /usr/src/app/ COPY docker/platformio.ini /usr/src/app/
RUN platformio settings set enable_telemetry No && \ RUN platformio settings set enable_telemetry No && \
@@ -20,7 +19,8 @@ RUN platformio settings set enable_telemetry No && \
COPY . . COPY . .
RUN pip install --no-cache-dir -e . && \ RUN pip install --no-cache-dir -e . && \
pip install --no-cache-dir tzlocal pip install --no-cache-dir tzlocal pillow
WORKDIR /config WORKDIR /config
ENTRYPOINT ["esphomeyaml"] ENTRYPOINT ["esphomeyaml"]
CMD ["/config", "dashboard"]

View File

@@ -3,4 +3,4 @@ FROM python:2.7
COPY requirements.txt /requirements.txt COPY requirements.txt /requirements.txt
RUN pip install -r /requirements.txt && \ RUN pip install -r /requirements.txt && \
pip install flake8==3.5.0 pylint==1.8.4 tzlocal pillow pip install flake8==3.5.0 pylint==1.9.3 tzlocal pillow

View File

@@ -13,23 +13,15 @@ from esphomeyaml.const import CONF_BAUD_RATE, CONF_BUILD_PATH, CONF_DOMAIN, CONF
CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_USE_CUSTOM_CODE, \ CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_USE_CUSTOM_CODE, \
CONF_WIFI, ESP_PLATFORM_ESP8266 CONF_WIFI, ESP_PLATFORM_ESP8266
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, _EXPRESSIONS, add, \ from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, \
add_job, color, flush_tasks, indent, quote, statement _EXPRESSIONS, add, \
add_job, color, flush_tasks, indent, quote, statement, relative_path
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'web_server', 'i2c'] PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'web_server', 'i2c']
def get_name(config):
return config[CONF_ESPHOMEYAML][CONF_NAME]
def get_base_path(config):
build_path = config[CONF_ESPHOMEYAML].get(CONF_BUILD_PATH, get_name(config))
return os.path.join(os.path.dirname(core.CONFIG_PATH), build_path)
def get_serial_ports(): def get_serial_ports():
# from https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports.py # from https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports.py
from serial.tools.list_ports import comports from serial.tools.list_ports import comports
@@ -99,7 +91,12 @@ def run_platformio(*cmd, **kwargs):
def run_miniterm(config, port, escape=False): def run_miniterm(config, port, escape=False):
import serial import serial
baud_rate = config.get(CONF_LOGGER, {}).get(CONF_BAUD_RATE, 115200) if CONF_LOGGER not in config:
_LOGGER.info("Logger is not enabled. Not starting UART logs.")
return
baud_rate = config['logger'][CONF_BAUD_RATE]
if baud_rate == 0:
_LOGGER.info("UART logging is disabled (baud_rate=0). Not starting UART logs.")
_LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate) _LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate)
with serial.Serial(port, baudrate=baud_rate) as ser: with serial.Serial(port, baudrate=baud_rate) as ser:
@@ -148,17 +145,19 @@ def write_cpp(config):
exp = exp.rhs exp = exp.rhs
all_code.append(unicode(statement(exp))) all_code.append(unicode(statement(exp)))
writer.write_platformio_project(config, get_base_path(config)) build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
writer.write_platformio_project(config, build_path)
code_s = indent('\n'.join(line.rstrip() for line in all_code)) code_s = indent('\n'.join(line.rstrip() for line in all_code))
cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp') cpp_path = os.path.join(build_path, 'src', 'main.cpp')
writer.write_cpp(code_s, cpp_path) writer.write_cpp(code_s, cpp_path)
return 0 return 0
def compile_program(args, config): def compile_program(args, config):
_LOGGER.info("Compiling app...") _LOGGER.info("Compiling app...")
command = ['platformio', 'run', '-d', get_base_path(config)] build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
command = ['platformio', 'run', '-d', build_path]
if args.verbose: if args.verbose:
command.append('-v') command.append('-v')
return run_platformio(*command) return run_platformio(*command)
@@ -177,8 +176,8 @@ def get_upload_host(config):
def upload_using_esptool(config, port): def upload_using_esptool(config, port):
import esptool import esptool
name = get_name(config) build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
path = os.path.join(get_base_path(config), '.pioenvs', name, 'firmware.bin') path = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
# pylint: disable=protected-access # pylint: disable=protected-access
return run_platformio('esptool.py', '--before', 'default_reset', '--after', 'hard_reset', return run_platformio('esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
'--chip', 'esp8266', '--port', port, 'write_flash', '0x0', '--chip', 'esp8266', '--port', port, 'write_flash', '0x0',
@@ -187,13 +186,14 @@ def upload_using_esptool(config, port):
def upload_program(config, args, port): def upload_program(config, args, port):
_LOGGER.info("Uploading binary...") _LOGGER.info("Uploading binary...")
build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
# if upload is to a serial port use platformio, otherwise assume ota # if upload is to a serial port use platformio, otherwise assume ota
serial_port = port.startswith('/') or port.startswith('COM') serial_port = port.startswith('/') or port.startswith('COM')
if port != 'OTA' and serial_port: if port != 'OTA' and serial_port:
if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266 and args.use_esptoolpy: if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266 and args.use_esptoolpy:
return upload_using_esptool(config, port) return upload_using_esptool(config, port)
command = ['platformio', 'run', '-d', get_base_path(config), command = ['platformio', 'run', '-d', build_path,
'-t', 'upload', '--upload-port', port] '-t', 'upload', '--upload-port', port]
if args.verbose: if args.verbose:
command.append('-v') command.append('-v')
@@ -213,7 +213,7 @@ def upload_program(config, args, port):
from esphomeyaml.components import ota from esphomeyaml.components import ota
from esphomeyaml import espota from esphomeyaml import espota
bin_file = os.path.join(get_base_path(config), '.pioenvs', get_name(config), 'firmware.bin') bin_file = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
if args.host_port is not None: if args.host_port is not None:
host_port = args.host_port host_port = args.host_port
else: else:
@@ -451,6 +451,8 @@ def parse_args(argv):
default=6052) default=6052)
dashboard.add_argument("--password", help="The optional password to require for all requests.", dashboard.add_argument("--password", help="The optional password to require for all requests.",
type=str, default='') type=str, default='')
dashboard.add_argument("--open-ui", help="Open the dashboard UI in a browser.",
action='store_true')
return parser.parse_args(argv[1:]) return parser.parse_args(argv[1:])

View File

@@ -33,7 +33,7 @@ DelayedOffFilter = binary_sensor_ns.DelayedOffFilter
HeartbeatFilter = binary_sensor_ns.HeartbeatFilter HeartbeatFilter = binary_sensor_ns.HeartbeatFilter
MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent
FILTER_KEYS = [CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA] FILTER_KEYS = [CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA, CONF_HEARTBEAT]
FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
vol.Optional(CONF_INVERT): None, vol.Optional(CONF_INVERT): None,

View File

@@ -4,8 +4,10 @@ import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.components import display from esphomeyaml.components import display
from esphomeyaml.components.display import ssd1306_spi from esphomeyaml.components.display import ssd1306_spi
from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, CONF_RESET_PIN from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, \
from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression CONF_MODEL, CONF_RESET_PIN, CONF_LAMBDA
from esphomeyaml.helpers import App, Pvariable, add, \
gpio_output_pin_expression, process_lambda
DEPENDENCIES = ['i2c'] DEPENDENCIES = ['i2c']
@@ -32,6 +34,11 @@ def to_code(config):
add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC])) add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC]))
if CONF_ADDRESS in config: if CONF_ADDRESS in config:
add(ssd.set_address(config[CONF_ADDRESS])) add(ssd.set_address(config[CONF_ADDRESS]))
if CONF_LAMBDA in config:
for lambda_ in process_lambda(config[CONF_LAMBDA],
[(display.DisplayBufferRef, 'it')]):
yield
add(ssd.set_writer(lambda_))
display.setup_display(ssd, config) display.setup_display(ssd, config)

View File

@@ -4,9 +4,11 @@ import esphomeyaml.config_validation as cv
from esphomeyaml import pins from esphomeyaml import pins
from esphomeyaml.components import display from esphomeyaml.components import display
from esphomeyaml.components.spi import SPIComponent from esphomeyaml.components.spi import SPIComponent
from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, \ from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, \
CONF_RESET_PIN, CONF_SPI_ID CONF_ID, CONF_MODEL, \
from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression CONF_RESET_PIN, CONF_SPI_ID, CONF_LAMBDA
from esphomeyaml.helpers import App, Pvariable, add, get_variable, \
gpio_output_pin_expression, process_lambda
DEPENDENCIES = ['spi'] DEPENDENCIES = ['spi']
@@ -16,9 +18,11 @@ MODELS = {
'SSD1306_128X32': display.display_ns.SSD1306_MODEL_128_32, 'SSD1306_128X32': display.display_ns.SSD1306_MODEL_128_32,
'SSD1306_128X64': display.display_ns.SSD1306_MODEL_128_64, 'SSD1306_128X64': display.display_ns.SSD1306_MODEL_128_64,
'SSD1306_96X16': display.display_ns.SSD1306_MODEL_96_16, 'SSD1306_96X16': display.display_ns.SSD1306_MODEL_96_16,
'SSD1306_64X48': display.display_ns.SSD1306_MODEL_64_48,
'SH1106_128X32': display.display_ns.SH1106_MODEL_128_32, 'SH1106_128X32': display.display_ns.SH1106_MODEL_128_32,
'SH1106_128X64': display.display_ns.SH1106_MODEL_128_64, 'SH1106_128X64': display.display_ns.SH1106_MODEL_128_64,
'SH1106_96X16': display.display_ns.SH1106_MODEL_96_16, 'SH1106_96X16': display.display_ns.SH1106_MODEL_96_16,
'SH1106_64X48': display.display_ns.SH1106_MODEL_64_48,
} }
SSD1306_MODEL = vol.All(vol.Upper, vol.Replace(' ', '_'), cv.one_of(*MODELS)) SSD1306_MODEL = vol.All(vol.Upper, vol.Replace(' ', '_'), cv.one_of(*MODELS))
@@ -52,6 +56,11 @@ def to_code(config):
add(ssd.set_reset_pin(reset)) add(ssd.set_reset_pin(reset))
if CONF_EXTERNAL_VCC in config: if CONF_EXTERNAL_VCC in config:
add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC])) add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC]))
if CONF_LAMBDA in config:
for lambda_ in process_lambda(config[CONF_LAMBDA],
[(display.DisplayBufferRef, 'it')]):
yield
add(ssd.set_writer(lambda_))
display.setup_display(ssd, config) display.setup_display(ssd, config)

View File

@@ -35,7 +35,7 @@ LogComponent = esphomelib_ns.LogComponent
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(vol.Schema({
cv.GenerateID(): cv.declare_variable_id(LogComponent), cv.GenerateID(): cv.declare_variable_id(LogComponent),
vol.Optional(CONF_BAUD_RATE): cv.positive_int, vol.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
vol.Optional(CONF_TX_BUFFER_SIZE): cv.validate_bytes, vol.Optional(CONF_TX_BUFFER_SIZE): cv.validate_bytes,
vol.Optional(CONF_LEVEL): is_log_level, vol.Optional(CONF_LEVEL): is_log_level,
vol.Optional(CONF_LOGS): vol.Schema({ vol.Optional(CONF_LOGS): vol.Schema({

View File

@@ -100,7 +100,7 @@ def to_code(config):
mqtt = Pvariable(config[CONF_ID], rhs) mqtt = Pvariable(config[CONF_ID], rhs)
if not config.get(CONF_DISCOVERY, True): if not config.get(CONF_DISCOVERY, True):
add(mqtt.disable_discovery()) add(mqtt.disable_discovery())
if CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config: elif CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config:
discovery_retain = config.get(CONF_DISCOVERY_RETAIN, True) discovery_retain = config.get(CONF_DISCOVERY_RETAIN, True)
discovery_prefix = config.get(CONF_DISCOVERY_PREFIX, 'homeassistant') discovery_prefix = config.get(CONF_DISCOVERY_PREFIX, 'homeassistant')
add(mqtt.set_discovery_info(discovery_prefix, discovery_retain)) add(mqtt.set_discovery_info(discovery_prefix, discovery_retain))

View File

@@ -1,10 +1,10 @@
import voluptuous as vol import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml import core from esphomeyaml import core
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \ from esphomeyaml.const import CONF_AP, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \
CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_REBOOT_TIMEOUT, \ CONF_GATEWAY, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_PASSWORD, CONF_POWER_SAVE_MODE,\
CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, ESP_PLATFORM_ESP8266 CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, CONF_SUBNET, ESP_PLATFORM_ESP8266
from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, esphomelib_ns, global_ns from esphomeyaml.helpers import App, Pvariable, StructInitializer, add, esphomelib_ns, global_ns
@@ -70,6 +70,12 @@ ManualIP = esphomelib_ns.ManualIP
WiFiComponent = esphomelib_ns.WiFiComponent WiFiComponent = esphomelib_ns.WiFiComponent
WiFiAp = esphomelib_ns.WiFiAp WiFiAp = esphomelib_ns.WiFiAp
WIFI_POWER_SAVE_MODES = {
'NONE': esphomelib_ns.WIFI_POWER_SAVE_NONE,
'LIGHT': esphomelib_ns.WIFI_POWER_SAVE_LIGHT,
'HIGH': esphomelib_ns.WIFI_POWER_SAVE_HIGH,
}
CONFIG_SCHEMA = vol.All(vol.Schema({ CONFIG_SCHEMA = vol.All(vol.Schema({
cv.GenerateID(): cv.declare_variable_id(WiFiComponent), cv.GenerateID(): cv.declare_variable_id(WiFiComponent),
vol.Optional(CONF_SSID): cv.ssid, vol.Optional(CONF_SSID): cv.ssid,
@@ -79,6 +85,7 @@ CONFIG_SCHEMA = vol.All(vol.Schema({
vol.Optional(CONF_HOSTNAME): cv.hostname, vol.Optional(CONF_HOSTNAME): cv.hostname,
vol.Optional(CONF_DOMAIN, default='.local'): cv.domainname, vol.Optional(CONF_DOMAIN, default='.local'): cv.domainname,
vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds, vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds,
vol.Optional(CONF_POWER_SAVE_MODE): vol.All(vol.Upper, cv.one_of(*WIFI_POWER_SAVE_MODES)),
}), validate) }), validate)
@@ -127,6 +134,9 @@ def to_code(config):
if CONF_REBOOT_TIMEOUT in config: if CONF_REBOOT_TIMEOUT in config:
add(wifi.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) add(wifi.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
if CONF_POWER_SAVE_MODE in config:
add(wifi.set_power_save_mode(WIFI_POWER_SAVE_MODES[CONF_POWER_SAVE_MODE]))
def lib_deps(config): def lib_deps(config):
if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266: if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:

View File

@@ -1,6 +1,6 @@
{ {
"name": "esphomeyaml", "name": "esphomeyaml",
"version": "1.8.0", "version": "1.8.2",
"slug": "esphomeyaml", "slug": "esphomeyaml",
"description": "esphomeyaml HassIO add-on for intelligently managing all your ESP8266/ESP32 devices.", "description": "esphomeyaml HassIO add-on for intelligently managing all your ESP8266/ESP32 devices.",
"url": "https://esphomelib.com/esphomeyaml/index.html", "url": "https://esphomelib.com/esphomeyaml/index.html",

View File

@@ -28,7 +28,7 @@ def get_component(domain):
path = 'esphomeyaml.components.{}'.format(domain) path = 'esphomeyaml.components.{}'.format(domain)
try: try:
module = importlib.import_module(path) module = importlib.import_module(path)
except ImportError as err: except (ImportError, ValueError) as err:
_LOGGER.debug(err) _LOGGER.debug(err)
else: else:
_COMPONENT_CACHE[domain] = module _COMPONENT_CACHE[domain] = module
@@ -183,7 +183,7 @@ def validate_config(config):
p_domain = u'{}.{}'.format(domain, p_name) p_domain = u'{}.{}'.format(domain, p_name)
platform = get_platform(domain, p_name) platform = get_platform(domain, p_name)
if platform is None: if platform is None:
result.add_error(u"Platform not found: {}".format(p_domain), p_domain, p_config) result.add_error(u"Platform not found: '{}'".format(p_domain), p_domain, p_config)
continue continue
success = True success = True

View File

@@ -2,10 +2,10 @@
MAJOR_VERSION = 1 MAJOR_VERSION = 1
MINOR_VERSION = 8 MINOR_VERSION = 8
PATCH_VERSION = '0' PATCH_VERSION = '2'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
ESPHOMELIB_VERSION = '1.8.0' ESPHOMELIB_VERSION = '1.8.2'
ESP_PLATFORM_ESP32 = 'ESP32' ESP_PLATFORM_ESP32 = 'ESP32'
ESP_PLATFORM_ESP8266 = 'ESP8266' ESP_PLATFORM_ESP8266 = 'ESP8266'
@@ -338,6 +338,7 @@ CONF_DAYS_OF_MONTH = 'days_of_month'
CONF_MONTHS = 'months' CONF_MONTHS = 'months'
CONF_DAYS_OF_WEEK = 'days_of_week' CONF_DAYS_OF_WEEK = 'days_of_week'
CONF_CRON = 'cron' CONF_CRON = 'cron'
CONF_POWER_SAVE_MODE = 'power_save_mode'
ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_' ALLOWED_NAME_CHARS = u'abcdefghijklmnopqrstuvwxyz0123456789_'
ARDUINO_VERSION_ESP32_DEV = 'https://github.com/platformio/platform-espressif32.git#feature/stage' ARDUINO_VERSION_ESP32_DEV = 'https://github.com/platformio/platform-espressif32.git#feature/stage'

View File

@@ -242,3 +242,4 @@ CONFIG_PATH = None
ESP_PLATFORM = '' ESP_PLATFORM = ''
BOARD = '' BOARD = ''
RAW_CONFIG = None RAW_CONFIG = None
NAME = ''

View File

@@ -1,5 +1,7 @@
import logging
import os import os
import re import re
import subprocess
import voluptuous as vol import voluptuous as vol
@@ -15,6 +17,8 @@ from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.helpers import App, NoArg, Pvariable, add, const_char_p, esphomelib_ns, \ from esphomeyaml.helpers import App, NoArg, Pvariable, add, const_char_p, esphomelib_ns, \
relative_path relative_path
_LOGGER = logging.getLogger(__name__)
LIBRARY_URI_REPO = u'https://github.com/OttoWinter/esphomelib.git' LIBRARY_URI_REPO = u'https://github.com/OttoWinter/esphomelib.git'
BUILD_FLASH_MODES = ['qio', 'qout', 'dio', 'dout'] BUILD_FLASH_MODES = ['qio', 'qout', 'dio', 'dout']
@@ -42,11 +46,20 @@ def validate_board(value):
def validate_simple_esphomelib_version(value): def validate_simple_esphomelib_version(value):
value = cv.string_strict(value) value = cv.string_strict(value)
if value.upper() == 'LATEST': if value.upper() == 'LATEST':
return LIBRARY_URI_REPO + '#v{}'.format(ESPHOMELIB_VERSION) return {
CONF_REPOSITORY: LIBRARY_URI_REPO,
CONF_TAG: 'v' + ESPHOMELIB_VERSION,
}
elif value.upper() == 'DEV': elif value.upper() == 'DEV':
return LIBRARY_URI_REPO return {
CONF_REPOSITORY: LIBRARY_URI_REPO,
CONF_BRANCH: 'master'
}
elif VERSION_REGEX.match(value) is not None: elif VERSION_REGEX.match(value) is not None:
return LIBRARY_URI_REPO + '#v{}'.format(value) return {
CONF_REPOSITORY: LIBRARY_URI_REPO,
CONF_TAG: 'v' + value,
}
return value return value
@@ -60,12 +73,11 @@ def validate_local_esphomelib_version(value):
return value return value
def convert_esphomelib_version_schema(value): def validate_commit(value):
if CONF_COMMIT in value: value = cv.string(value)
return value[CONF_REPOSITORY] + '#' + value[CONF_COMMIT] if re.match(r"^[0-9a-f]{7,}$", value) is None:
if CONF_BRANCH in value: raise vol.Invalid("Commit option only accepts commit hashes in hex format.")
return value[CONF_REPOSITORY] + '#' + value[CONF_BRANCH] return value
return value[CONF_REPOSITORY] + '#' + value[CONF_TAG]
ESPHOMELIB_VERSION_SCHEMA = vol.Any( ESPHOMELIB_VERSION_SCHEMA = vol.Any(
@@ -76,12 +88,11 @@ ESPHOMELIB_VERSION_SCHEMA = vol.Any(
vol.All( vol.All(
vol.Schema({ vol.Schema({
vol.Optional(CONF_REPOSITORY, default=LIBRARY_URI_REPO): cv.string, vol.Optional(CONF_REPOSITORY, default=LIBRARY_URI_REPO): cv.string,
vol.Optional(CONF_COMMIT, 'tag'): cv.string, vol.Optional(CONF_COMMIT): validate_commit,
vol.Optional(CONF_BRANCH, 'tag'): cv.string, vol.Optional(CONF_BRANCH): cv.string,
vol.Optional(CONF_TAG, 'tag'): cv.string, vol.Optional(CONF_TAG): cv.string,
}), }),
cv.has_at_most_one_key(CONF_COMMIT, CONF_BRANCH, CONF_TAG), cv.has_at_most_one_key(CONF_COMMIT, CONF_BRANCH, CONF_TAG)
convert_esphomelib_version_schema
), ),
) )
@@ -108,8 +119,8 @@ PLATFORMIO_ESP8266_LUT = {
} }
PLATFORMIO_ESP32_LUT = { PLATFORMIO_ESP32_LUT = {
'1.0.0': 'espressif32@1.3.0', '1.0.0': 'espressif32@1.4.0',
'RECOMMENDED': 'espressif32@>=1.3.0', 'RECOMMENDED': 'espressif32@>=1.4.0',
'LATEST': 'espressif32', 'LATEST': 'espressif32',
'DEV': ARDUINO_VERSION_ESP32_DEV, 'DEV': ARDUINO_VERSION_ESP32_DEV,
} }
@@ -138,6 +149,10 @@ def validate_arduino_version(value):
raise NotImplementedError raise NotImplementedError
def default_build_path():
return core.NAME
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.valid_name, vol.Required(CONF_NAME): cv.valid_name,
vol.Required(CONF_PLATFORM): vol.All(vol.Upper, cv.one_of('ESP8266', 'ESPRESSIF8266', vol.Required(CONF_PLATFORM): vol.All(vol.Upper, cv.one_of('ESP8266', 'ESPRESSIF8266',
@@ -146,7 +161,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_ESPHOMELIB_VERSION, default='latest'): ESPHOMELIB_VERSION_SCHEMA, vol.Optional(CONF_ESPHOMELIB_VERSION, default='latest'): ESPHOMELIB_VERSION_SCHEMA,
vol.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version, vol.Optional(CONF_ARDUINO_VERSION, default='recommended'): validate_arduino_version,
vol.Optional(CONF_USE_CUSTOM_CODE, default=False): cv.boolean, vol.Optional(CONF_USE_CUSTOM_CODE, default=False): cv.boolean,
vol.Optional(CONF_BUILD_PATH): cv.string, vol.Optional(CONF_BUILD_PATH, default=default_build_path): cv.string,
vol.Optional(CONF_BOARD_FLASH_MODE): vol.All(vol.Lower, cv.one_of(*BUILD_FLASH_MODES)), vol.Optional(CONF_BOARD_FLASH_MODE): vol.All(vol.Lower, cv.one_of(*BUILD_FLASH_MODES)),
vol.Optional(CONF_ON_BOOT): vol.All(cv.ensure_list, [automation.validate_automation({ vol.Optional(CONF_ON_BOOT): vol.All(cv.ensure_list, [automation.validate_automation({
@@ -173,14 +188,52 @@ def preload_core_config(config):
raise ESPHomeYAMLError("esphomeyaml.platform not specified.") raise ESPHomeYAMLError("esphomeyaml.platform not specified.")
if CONF_BOARD not in core_conf: if CONF_BOARD not in core_conf:
raise ESPHomeYAMLError("esphomeyaml.board not specified.") raise ESPHomeYAMLError("esphomeyaml.board not specified.")
if CONF_NAME not in core_conf:
raise ESPHomeYAMLError("esphomeyaml.name not specified.")
try: try:
core.ESP_PLATFORM = validate_platform(core_conf[CONF_PLATFORM]) core.ESP_PLATFORM = validate_platform(core_conf[CONF_PLATFORM])
core.BOARD = validate_board(core_conf[CONF_BOARD]) core.BOARD = validate_board(core_conf[CONF_BOARD])
core.NAME = cv.valid_name(core_conf[CONF_NAME])
except vol.Invalid as e: except vol.Invalid as e:
raise ESPHomeYAMLError(unicode(e)) raise ESPHomeYAMLError(unicode(e))
def run_command(*args):
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
rc = p.returncode
return rc, stdout, stderr
def update_esphomelib_repo(config):
esphomelib_version = config[CONF_ESPHOMELIB_VERSION]
if CONF_REPOSITORY not in esphomelib_version:
return
build_path = relative_path(config[CONF_BUILD_PATH])
esphomelib_path = os.path.join(build_path, '.piolibdeps', 'esphomelib')
is_default_branch = all(x not in esphomelib_version
for x in (CONF_BRANCH, CONF_TAG, CONF_COMMIT))
if not (CONF_BRANCH in esphomelib_version or is_default_branch):
# Git commit hash or tag cannot be updated
return
rc, _, _ = run_command('git', '-C', esphomelib_path, '--help')
if rc != 0:
# git not installed or repo not downloaded yet
return
rc, _, _ = run_command('git', '-C', esphomelib_path, 'diff-index', '--quiet', 'HEAD', '--')
if rc != 0:
# local changes, cannot update
_LOGGER.warn("Local changes in esphomelib copy from git. Will not auto-update.")
return
rc, _, _ = run_command('git', '-C', esphomelib_path, 'pull')
if rc != 0:
_LOGGER.warn("Couldn't auto-update local git copy of esphomelib.")
return
def to_code(config): def to_code(config):
add(App.set_name(config[CONF_NAME])) add(App.set_name(config[CONF_NAME]))
@@ -197,3 +250,5 @@ def to_code(config):
rhs = App.register_component(LoopTrigger.new()) rhs = App.register_component(LoopTrigger.new())
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs) trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, NoArg, conf) automation.build_automation(trigger, NoArg, conf)
update_esphomelib_repo(config)

View File

@@ -9,10 +9,11 @@ import os
import random import random
import subprocess import subprocess
from esphomeyaml.const import CONF_ESPHOMEYAML, CONF_BUILD_PATH
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml import const, core, __main__ from esphomeyaml import const, core, __main__
from esphomeyaml.__main__ import get_serial_ports, get_base_path, get_name from esphomeyaml.__main__ import get_serial_ports
from esphomeyaml.helpers import quote from esphomeyaml.helpers import quote, relative_path
try: try:
import tornado import tornado
@@ -116,6 +117,13 @@ class EsphomeyamlValidateHandler(EsphomeyamlCommandWebSocket):
return ["esphomeyaml", config_file, "config"] return ["esphomeyaml", config_file, "config"]
class EsphomeyamlCleanMqttHandler(EsphomeyamlCommandWebSocket):
def build_command(self, message):
js = json.loads(message)
config_file = os.path.join(CONFIG_DIR, js['configuration'])
return ["esphomeyaml", config_file, "clean-mqtt"]
class SerialPortRequestHandler(BaseHandler): class SerialPortRequestHandler(BaseHandler):
def get(self): def get(self):
if not self.is_authenticated(): if not self.is_authenticated():
@@ -161,10 +169,10 @@ class DownloadBinaryRequestHandler(BaseHandler):
config_file = os.path.join(CONFIG_DIR, configuration) config_file = os.path.join(CONFIG_DIR, configuration)
core.CONFIG_PATH = config_file core.CONFIG_PATH = config_file
config = __main__.read_config(core.CONFIG_PATH) config = __main__.read_config(core.CONFIG_PATH)
name = get_name(config) build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
path = os.path.join(get_base_path(config), '.pioenvs', name, 'firmware.bin') path = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Type', 'application/octet-stream')
self.set_header("Content-Disposition", 'attachment; filename="{}.bin"'.format(name)) self.set_header("Content-Disposition", 'attachment; filename="{}.bin"'.format(core.NAME))
with open(path, 'rb') as f: with open(path, 'rb') as f:
while 1: while 1:
data = f.read(16384) # or some other nice-sized chunk data = f.read(16384) # or some other nice-sized chunk
@@ -212,6 +220,7 @@ def make_app(debug=False):
(r"/run", EsphomeyamlRunHandler), (r"/run", EsphomeyamlRunHandler),
(r"/compile", EsphomeyamlCompileHandler), (r"/compile", EsphomeyamlCompileHandler),
(r"/validate", EsphomeyamlValidateHandler), (r"/validate", EsphomeyamlValidateHandler),
(r"/clean-mqtt", EsphomeyamlCleanMqttHandler),
(r"/download.bin", DownloadBinaryRequestHandler), (r"/download.bin", DownloadBinaryRequestHandler),
(r"/serial-ports", SerialPortRequestHandler), (r"/serial-ports", SerialPortRequestHandler),
(r"/wizard.html", WizardRequestHandler), (r"/wizard.html", WizardRequestHandler),
@@ -250,6 +259,12 @@ def start_web_server(args):
args.port, CONFIG_DIR) args.port, CONFIG_DIR)
app = make_app(args.verbose) app = make_app(args.verbose)
app.listen(args.port) app.listen(args.port)
if args.open_ui:
import webbrowser
webbrowser.open('localhost:{}'.format(args.port))
try: try:
tornado.ioloop.IOLoop.current().start() tornado.ioloop.IOLoop.current().start()
except KeyboardInterrupt: except KeyboardInterrupt:

View File

@@ -159,6 +159,10 @@
margin-right: 24px; margin-right: 24px;
width: 350px; width: 350px;
} }
.dropdown-trigger {
cursor: pointer;
}
</style> </style>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
@@ -191,7 +195,7 @@
<main> <main>
<div class="container"> <div class="container">
{% for file, full_path in zip(files, full_path_files) %} {% for i, (file, full_path) in enumerate(zip(files, full_path_files)) %}
<div class="row"> <div class="row">
<div class="col s8 offset-s2 m10 offset-m1 l12"> <div class="col s8 offset-s2 m10 offset-m1 l12">
<div class="card horizontal"> <div class="card horizontal">
@@ -200,7 +204,10 @@
</div> </div>
<div class="card-stacked"> <div class="card-stacked">
<div class="card-content"> <div class="card-content">
<span class="card-title">{{ escape(file) }}</span> <span class="card-title">
{{ escape(file) }}
<i class="material-icons right dropdown-trigger" data-target="dropdown-{{ i }}">more_vert</i>
</span>
<p> <p>
Full path: <code class="inlinecode">{{ escape(full_path) }}</code> Full path: <code class="inlinecode">{{ escape(full_path) }}</code>
</p> </p>
@@ -211,6 +218,9 @@
<a href="#" class="action-show-logs" data-node="{{ file }}">Show Logs</a> <a href="#" class="action-show-logs" data-node="{{ file }}">Show Logs</a>
<a href="#" class="action-validate" data-node="{{ file }}">Validate</a> <a href="#" class="action-validate" data-node="{{ file }}">Validate</a>
</div> </div>
<ul id="dropdown-{{ i }}" class="dropdown-content">
<li><a href="#" class="action-clean-mqtt" data-node="{{ file }}">Clean MQTT</a></li>
</ul>
</div> </div>
</div> </div>
</div> </div>
@@ -462,6 +472,18 @@
</div> </div>
</div> </div>
<div id="modal-clean-mqtt" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Clean MQTT discovery <code class="inlinecode filename"></code></h4>
<div class="log-container">
<pre class="log"></pre>
</div>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Stop</a>
</div>
</div>
<a class="btn-floating btn-large ribbon-fab waves-effect waves-light pink accent-2" id="setup-wizard-start"> <a class="btn-floating btn-large ribbon-fab waves-effect waves-light pink accent-2" id="setup-wizard-start">
<i class="material-icons">add</i> <i class="material-icons">add</i>
</a> </a>
@@ -539,6 +561,7 @@
if (allEqual) if (allEqual)
return; return;
} }
const hasNewPort = response.length >= ports.length;
ports = response; ports = response;
@@ -559,7 +582,7 @@
} }
M.FormSelect.init(portSelect, {}); M.FormSelect.init(portSelect, {});
if (!begin) if (!begin && hasNewPort)
M.toast({html: "Discovered new serial port."}); M.toast({html: "Discovered new serial port."});
}); });
}; };
@@ -784,6 +807,48 @@
link.click(); link.click();
}); });
const cleanMqttModalElem = document.getElementById("modal-clean-mqtt");
document.querySelectorAll(".action-clean-mqtt").forEach((btn) => {
btn.addEventListener('click', (e) => {
configuration = e.target.getAttribute('data-node');
const modalInstance = M.Modal.getInstance(cleanMqttModalElem);
const log = cleanMqttModalElem.querySelector(".log");
log.innerHTML = "";
const stopLogsButton = cleanMqttModalElem.querySelector(".stop-logs");
let stopped = false;
stopLogsButton.innerHTML = "Stop";
modalInstance.open();
const filenameField = cleanMqttModalElem.querySelector('.filename');
filenameField.innerHTML = configuration;
const logSocket = new WebSocket(wsUrl + "/clean-mqtt");
logSocket.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.event === "line") {
const msg = data.data;
log.innerHTML += colorReplace(msg);
} else if (data.event === "exit") {
stopLogsButton.innerHTML = "Close";
stopped = true;
}
});
logSocket.addEventListener('open', () => {
const msg = JSON.stringify({configuration: configuration});
logSocket.send(msg);
});
logSocket.addEventListener('close', () => {
if (!stopped) {
M.toast({html: 'Terminated process.'});
}
});
modalInstance.options.onCloseStart = () => {
logSocket.close();
};
});
});
const modalSetupElem = document.getElementById("modal-wizard"); const modalSetupElem = document.getElementById("modal-wizard");
const setupWizardStart = document.getElementById('setup-wizard-start'); const setupWizardStart = document.getElementById('setup-wizard-start');
const startWizard = () => { const startWizard = () => {

View File

@@ -106,7 +106,7 @@ class ExpressionList(Expression):
self.args.append(exp) self.args.append(exp)
def __str__(self): def __str__(self):
text = u", ".join(str(x) for x in self.args) text = u", ".join(unicode(x) for x in self.args)
return indent_all_but_first_and_last(text) return indent_all_but_first_and_last(text)

View File

@@ -83,7 +83,9 @@ def clear_topic(config, topic, username=None, password=None, client_id=None):
discovery_prefix = config[CONF_MQTT].get(CONF_DISCOVERY_PREFIX, u'homeassistant') discovery_prefix = config[CONF_MQTT].get(CONF_DISCOVERY_PREFIX, u'homeassistant')
name = config[CONF_ESPHOMEYAML][CONF_NAME] name = config[CONF_ESPHOMEYAML][CONF_NAME]
topic = u'{}/+/{}/#'.format(discovery_prefix, name) topic = u'{}/+/{}/#'.format(discovery_prefix, name)
_LOGGER.info(u"Clearing messages from %s", topic) _LOGGER.info(u"Clearing messages from '%s'", topic)
_LOGGER.info(u"Please close this window when no more messages appear and the "
u"MQTT topic has been cleared of retained messages.")
def on_message(client, userdata, msg): def on_message(client, userdata, msg):
if not msg.payload or not msg.retain: if not msg.payload or not msg.retain:

View File

@@ -7,9 +7,9 @@ import os
from esphomeyaml import core from esphomeyaml import core
from esphomeyaml.config import iter_components from esphomeyaml.config import iter_components
from esphomeyaml.const import CONF_ARDUINO_VERSION, CONF_BOARD, CONF_BOARD_FLASH_MODE, \ from esphomeyaml.const import ARDUINO_VERSION_ESP32_DEV, CONF_ARDUINO_VERSION, CONF_BOARD, \
CONF_ESPHOMELIB_VERSION, CONF_ESPHOMEYAML, CONF_LOCAL, CONF_NAME, CONF_USE_CUSTOM_CODE, \ CONF_BOARD_FLASH_MODE, CONF_ESPHOMELIB_VERSION, CONF_ESPHOMEYAML, CONF_LOCAL, CONF_NAME, \
ESP_PLATFORM_ESP32, ARDUINO_VERSION_ESP32_DEV CONF_USE_CUSTOM_CODE, ESP_PLATFORM_ESP32, CONF_REPOSITORY, CONF_COMMIT, CONF_BRANCH, CONF_TAG
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.core_config import VERSION_REGEX from esphomeyaml.core_config import VERSION_REGEX
from esphomeyaml.helpers import relative_path from esphomeyaml.helpers import relative_path
@@ -60,8 +60,13 @@ lib_deps =
build_flags = build_flags =
{build_flags} {build_flags}
${{common.build_flags}} ${{common.build_flags}}
upload_speed = {upload_speed}
""" """
UPLOAD_SPEED_OVERRIDE = {
'esp210': 57600,
}
def get_build_flags(config, key): def get_build_flags(config, key):
build_flags = set() build_flags = set()
@@ -86,6 +91,7 @@ def get_ini_content(config, path):
u'platform': config[CONF_ESPHOMEYAML][CONF_ARDUINO_VERSION], u'platform': config[CONF_ESPHOMEYAML][CONF_ARDUINO_VERSION],
u'board': config[CONF_ESPHOMEYAML][CONF_BOARD], u'board': config[CONF_ESPHOMEYAML][CONF_BOARD],
u'build_flags': u'', u'build_flags': u'',
u'upload_speed': UPLOAD_SPEED_OVERRIDE.get(core.BOARD, 115200),
} }
build_flags = set() build_flags = set()
if not config[CONF_ESPHOMEYAML][CONF_USE_CUSTOM_CODE]: if not config[CONF_ESPHOMEYAML][CONF_USE_CUSTOM_CODE]:
@@ -105,8 +111,13 @@ def get_ini_content(config, path):
lib_version = config[CONF_ESPHOMEYAML][CONF_ESPHOMELIB_VERSION] lib_version = config[CONF_ESPHOMEYAML][CONF_ESPHOMELIB_VERSION]
lib_path = os.path.join(path, 'lib') lib_path = os.path.join(path, 'lib')
dst_path = os.path.join(lib_path, 'esphomelib') dst_path = os.path.join(lib_path, 'esphomelib')
if isinstance(lib_version, (str, unicode)): if CONF_REPOSITORY in lib_version:
lib_deps.add(lib_version) tag = next((lib_version[x] for x in (CONF_COMMIT, CONF_BRANCH, CONF_TAG)
if x in lib_version), None)
if tag is None:
lib_deps.add(lib_version[CONF_REPOSITORY])
else:
lib_deps.add(lib_version[CONF_REPOSITORY] + '#' + tag)
if os.path.islink(dst_path): if os.path.islink(dst_path):
os.unlink(dst_path) os.unlink(dst_path)
else: else:

View File

@@ -1,7 +1,7 @@
voluptuous==0.11.1 voluptuous>=0.11.1
platformio==3.5.2 platformio>=3.5.3
pyyaml==3.12 pyyaml>=3.12
paho-mqtt==1.3.1 paho-mqtt>=1.3.1
colorlog==3.1.2 colorlog>=3.1.2
tornado==5.0.2 tornado>=5.0.0
esptool==2.3.1 esptool>=2.3.1

View File

@@ -23,7 +23,7 @@ DOWNLOAD_URL = '{}/archive/{}.zip'.format(GITHUB_URL, const.__version__)
REQUIRES = [ REQUIRES = [
'voluptuous>=0.11.1', 'voluptuous>=0.11.1',
'platformio>=3.5.2', 'platformio>=3.5.3',
'pyyaml>=3.12', 'pyyaml>=3.12',
'paho-mqtt>=1.3.1', 'paho-mqtt>=1.3.1',
'colorlog>=3.1.2', 'colorlog>=3.1.2',

View File

@@ -21,7 +21,7 @@ esphomeyaml:
then: then:
- lambda: >- - lambda: >-
ESP_LOGV("main", "ON LOOP!"); ESP_LOGV("main", "ON LOOP!");
build_path: build build_path: build/test1
wifi: wifi:
ssid: 'MySSID' ssid: 'MySSID'
@@ -194,9 +194,6 @@ sensor:
retain: False retain: False
availability: availability:
state_topic: livingroom/custom_state_topic state_topic: livingroom/custom_state_topic
- platform: ble_rssi
mac_address: AC:37:43:77:5F:4C
name: "BLE Google Home Mini RSSI value"
- platform: bme280 - platform: bme280
temperature: temperature:
name: "Outside Temperature" name: "Outside Temperature"
@@ -427,26 +424,6 @@ sensor:
- platform: wifi_signal - platform: wifi_signal
name: "WiFi Signal Sensor" name: "WiFi Signal Sensor"
update_interval: 15s update_interval: 15s
- platform: xiaomi_miflora
mac_address: 94:2B:FF:5C:91:61
temperature:
name: "Xiaomi MiFlora Temperature"
moisture:
name: "Xiaomi MiFlora Moisture"
illuminance:
name: "Xiaomi MiFlora Illuminance"
conductivity:
name: "Xiaomi MiFlora Soil Conductivity"
battery_level:
name: "Xiaomi MiFlora Battery Level"
- platform: xiaomi_mijia
mac_address: 7A:80:8E:19:36:BA
temperature:
name: "Xiaomi MiJia Temperature"
humidity:
name: "Xiaomi MiJia Humidity"
battery_level:
name: "Xiaomi MiJia Battery Level"
esp32_touch: esp32_touch:
@@ -467,6 +444,7 @@ binary_sensor:
- invert: - invert:
- delayed_on: 40ms - delayed_on: 40ms
- delayed_off: 40ms - delayed_off: 40ms
- heartbeat: 1s
on_press: on_press:
then: then:
- lambda: >- - lambda: >-
@@ -496,9 +474,6 @@ binary_sensor:
id: binary_sensor1 id: binary_sensor1
- platform: status - platform: status
name: "Living Room Status" name: "Living Room Status"
- platform: esp32_ble_tracker
mac_address: AC:37:43:77:5F:4C
name: "ESP32 BLE Tracker Google Home Mini"
- platform: esp32_touch - platform: esp32_touch
name: "ESP32 Touch Pad GPIO27" name: "ESP32 Touch Pad GPIO27"
pin: GPIO27 pin: GPIO27
@@ -888,13 +863,6 @@ remote_receiver:
pin: GPIO32 pin: GPIO32
dump: all dump: all
esp32_ble_tracker:
scan_interval: 300s
esp32_ble_beacon:
type: iBeacon
uuid: 'c29ce823-e67a-4e71-bff2-abaa32e77a98'
status_led: status_led:
pin: GPIO2 pin: GPIO2

102
tests/test2.yaml Normal file
View File

@@ -0,0 +1,102 @@
esphomeyaml:
name: test1
platform: ESP32
board: nodemcu-32s
# Use latest upstream esphomelib git version.
esphomelib_version: dev
# Use this for testing while developing:
# esphomelib_version:
# local: ~/path/to/esphomelib
use_custom_code: true
build_path: build/test2
wifi:
ssid: 'MySSID'
password: 'password1'
reboot_timeout: 120s
mqtt:
broker: '192.168.178.84'
port: 1883
username: 'debug'
password: 'debug'
i2c:
sda: 21
scl: 22
scan: False
spi:
clk_pin: GPIO21
mosi_pin: GPIO22
miso_pin: GPIO23
uart:
tx_pin: GPIO22
rx_pin: GPIO23
baud_rate: 115200
ota:
safe_mode: True
port: 3286
logger:
level: DEBUG
web_server:
deep_sleep:
run_duration: 20s
sleep_duration: 50s
sensor:
- platform: ble_rssi
mac_address: AC:37:43:77:5F:4C
name: "BLE Google Home Mini RSSI value"
- platform: xiaomi_miflora
mac_address: 94:2B:FF:5C:91:61
temperature:
name: "Xiaomi MiFlora Temperature"
moisture:
name: "Xiaomi MiFlora Moisture"
illuminance:
name: "Xiaomi MiFlora Illuminance"
conductivity:
name: "Xiaomi MiFlora Soil Conductivity"
battery_level:
name: "Xiaomi MiFlora Battery Level"
- platform: xiaomi_mijia
mac_address: 7A:80:8E:19:36:BA
temperature:
name: "Xiaomi MiJia Temperature"
humidity:
name: "Xiaomi MiJia Humidity"
battery_level:
name: "Xiaomi MiJia Battery Level"
esp32_touch:
setup_mode: True
binary_sensor:
- platform: esp32_ble_tracker
mac_address: AC:37:43:77:5F:4C
name: "ESP32 BLE Tracker Google Home Mini"
- platform: esp32_touch
name: "ESP32 Touch Pad GPIO27"
pin: GPIO27
threshold: 1000
remote_receiver:
pin: GPIO32
dump: []
esp32_ble_tracker:
scan_interval: 300s
esp32_ble_beacon:
type: iBeacon
uuid: 'c29ce823-e67a-4e71-bff2-abaa32e77a98'
status_led:
pin: GPIO2