mirror of
https://github.com/esphome/esphome.git
synced 2025-11-13 13:25:50 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7671f0c90 | ||
|
|
639b97ccb2 | ||
|
|
0374b3a0b3 | ||
|
|
7ce753b76f | ||
|
|
05a1089ed2 | ||
|
|
71947bb6ac | ||
|
|
ef54e33b70 | ||
|
|
12f20fc3cf | ||
|
|
ffdcddc18e | ||
|
|
85d70eb5a0 | ||
|
|
ffb793177a | ||
|
|
d3f2fab88a | ||
|
|
0fa52d0ce6 | ||
|
|
cf264a2743 | ||
|
|
433b605bef | ||
|
|
6e60c6493a | ||
|
|
4e63bc96d5 | ||
|
|
ce4b339d16 | ||
|
|
ab6d293d0d | ||
|
|
5e5137960d |
@@ -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"
|
||||||
|
|
||||||
|
|||||||
16
.travis.yml
16
.travis.yml
@@ -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
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:])
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -242,3 +242,4 @@ CONFIG_PATH = None
|
|||||||
ESP_PLATFORM = ''
|
ESP_PLATFORM = ''
|
||||||
BOARD = ''
|
BOARD = ''
|
||||||
RAW_CONFIG = None
|
RAW_CONFIG = None
|
||||||
|
NAME = ''
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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 = () => {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -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',
|
||||||
|
|||||||
@@ -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
102
tests/test2.yaml
Normal 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
|
||||||
Reference in New Issue
Block a user