mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 00:51:49 +00:00 
			
		
		
		
	Compare commits
	
		
			143 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ac0b095941 | ||
| 
						 | 
					cda9bad233 | ||
| 
						 | 
					41db8a1264 | ||
| 
						 | 
					e7e785fd60 | ||
| 
						 | 
					300d3a1f46 | ||
| 
						 | 
					356554c08d | ||
| 
						 | 
					ced28ad006 | ||
| 
						 | 
					6ccab2bef9 | ||
| 
						 | 
					475aa4879c | ||
| 
						 | 
					4452473735 | ||
| 
						 | 
					948adfd28c | ||
| 
						 | 
					aebbd7673b | ||
| 
						 | 
					3baaf6b7c4 | ||
| 
						 | 
					4a14221e2b | ||
| 
						 | 
					114ebf9fe1 | ||
| 
						 | 
					92a4ee5652 | ||
| 
						 | 
					9fea094b4e | ||
| 
						 | 
					596c334fcb | ||
| 
						 | 
					ca4450858f | ||
| 
						 | 
					f3ec83fe31 | ||
| 
						 | 
					c4ada8c9f0 | ||
| 
						 | 
					23df5d8af7 | ||
| 
						 | 
					289acade1e | ||
| 
						 | 
					a99f99779a | ||
| 
						 | 
					5c14ca030a | ||
| 
						 | 
					0fc6a027a7 | ||
| 
						 | 
					3c0d97ef69 | ||
| 
						 | 
					5b4f98d414 | ||
| 
						 | 
					7ebfcd3807 | ||
| 
						 | 
					3ef0634dd2 | ||
| 
						 | 
					0928c9739f | ||
| 
						 | 
					e009f21a72 | ||
| 
						 | 
					606c412616 | ||
| 
						 | 
					975b5127d6 | ||
| 
						 | 
					60c9ffef30 | ||
| 
						 | 
					99861259d7 | ||
| 
						 | 
					067ec30c56 | ||
| 
						 | 
					5a102c2ab7 | ||
| 
						 | 
					4b017e2096 | ||
| 
						 | 
					8495ce96a3 | ||
| 
						 | 
					55caf4f648 | ||
| 
						 | 
					c123f0091d | ||
| 
						 | 
					7c65d44976 | ||
| 
						 | 
					5b8d12a80c | ||
| 
						 | 
					3951a2b22a | ||
| 
						 | 
					69a74a30e8 | ||
| 
						 | 
					f3ee5b55e9 | ||
| 
						 | 
					f6cc9f7caa | ||
| 
						 | 
					a5d0ecdb13 | ||
| 
						 | 
					71cbc9cfb0 | ||
| 
						 | 
					88625c656d | ||
| 
						 | 
					971b15ac67 | ||
| 
						 | 
					a4edcc48ca | ||
| 
						 | 
					1778dd4df9 | ||
| 
						 | 
					311e837196 | ||
| 
						 | 
					3b00cfd6c4 | ||
| 
						 | 
					1c7ca4bc6f | ||
| 
						 | 
					38e7b597d6 | ||
| 
						 | 
					808ee19180 | ||
| 
						 | 
					c2a0c22bd9 | ||
| 
						 | 
					e785ad5401 | ||
| 
						 | 
					bacddc3673 | ||
| 
						 | 
					7dd0dabaf5 | ||
| 
						 | 
					92f8b043ce | ||
| 
						 | 
					2e5fd7e90d | ||
| 
						 | 
					407c46cb03 | ||
| 
						 | 
					12ce448f2d | ||
| 
						 | 
					340530566c | ||
| 
						 | 
					f4a55eafd7 | ||
| 
						 | 
					fc8f270a9f | ||
| 
						 | 
					e7ce8f7a13 | ||
| 
						 | 
					3d1cce2a29 | ||
| 
						 | 
					6be47488a4 | ||
| 
						 | 
					5b94bb894e | ||
| 
						 | 
					26aa399bea | ||
| 
						 | 
					af0c213024 | ||
| 
						 | 
					88e036ddb2 | ||
| 
						 | 
					8012de3ba4 | ||
| 
						 | 
					e2b1d5438d | ||
| 
						 | 
					fe66f93a01 | ||
| 
						 | 
					581dffe2d4 | ||
| 
						 | 
					6f22006bf7 | ||
| 
						 | 
					fe54700687 | ||
| 
						 | 
					f0c0131ed1 | ||
| 
						 | 
					52750d933b | ||
| 
						 | 
					7e7a85abfd | ||
| 
						 | 
					c1b8107aaf | ||
| 
						 | 
					0bdcce609f | ||
| 
						 | 
					6b702f8014 | ||
| 
						 | 
					078ab26fd2 | ||
| 
						 | 
					1404d39ffe | ||
| 
						 | 
					b71b14cd06 | ||
| 
						 | 
					145e7b00ee | ||
| 
						 | 
					07c80dfcda | ||
| 
						 | 
					0e52c9a778 | ||
| 
						 | 
					94bd179256 | ||
| 
						 | 
					11c38ca4e8 | ||
| 
						 | 
					dc71d11a21 | ||
| 
						 | 
					e385c8435b | ||
| 
						 | 
					13eca6012d | ||
| 
						 | 
					cb3e3e024d | ||
| 
						 | 
					79bdec32b8 | ||
| 
						 | 
					c153dba5bc | ||
| 
						 | 
					fa2c2917c1 | ||
| 
						 | 
					2a06f4dbf4 | ||
| 
						 | 
					49b618bb0c | ||
| 
						 | 
					20ec3900be | ||
| 
						 | 
					605be1a6ec | ||
| 
						 | 
					33b67de32e | ||
| 
						 | 
					1ffedb291c | ||
| 
						 | 
					8f251848ef | ||
| 
						 | 
					4046a16d85 | ||
| 
						 | 
					5ed987adcd | ||
| 
						 | 
					a463c59733 | ||
| 
						 | 
					1726c4237b | ||
| 
						 | 
					f1241af91d | ||
| 
						 | 
					7ae6777fd6 | ||
| 
						 | 
					a169d37557 | ||
| 
						 | 
					be21aa786d | ||
| 
						 | 
					9a881100e6 | ||
| 
						 | 
					c2f88776c7 | ||
| 
						 | 
					846fcb8ccd | ||
| 
						 | 
					44495c919c | ||
| 
						 | 
					d4ce7699d4 | ||
| 
						 | 
					318bb8b254 | ||
| 
						 | 
					1ad65516cf | ||
| 
						 | 
					d4c7e6c634 | ||
| 
						 | 
					9a939d2d27 | ||
| 
						 | 
					06eeed9ee9 | ||
| 
						 | 
					5655b5fe10 | ||
| 
						 | 
					0dec7cfbf8 | ||
| 
						 | 
					f51d301d53 | ||
| 
						 | 
					30e7797577 | ||
| 
						 | 
					0e5cabadc1 | ||
| 
						 | 
					aa5f887ff3 | ||
| 
						 | 
					28561ea6a4 | ||
| 
						 | 
					6b8125f5f2 | ||
| 
						 | 
					ab43390983 | ||
| 
						 | 
					d7d3a4aa36 | ||
| 
						 | 
					4dce7fa103 | ||
| 
						 | 
					467ef9902f | ||
| 
						 | 
					6a2e9a8503 | ||
| 
						 | 
					74fefea5bb | 
							
								
								
									
										7
									
								
								.github/issue-close-app.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.github/issue-close-app.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
comment: >-
 | 
			
		||||
  https://github.com/esphome/esphome/issues/430
 | 
			
		||||
issueConfigs:
 | 
			
		||||
- content:
 | 
			
		||||
  - "OTHERWISE THE ISSUE WILL BE CLOSED AUTOMATICALLY"
 | 
			
		||||
 | 
			
		||||
caseInsensitive: false
 | 
			
		||||
@@ -41,11 +41,11 @@ stages:
 | 
			
		||||
 | 
			
		||||
    - |
 | 
			
		||||
      if [[ "${IS_HASSIO}" == "YES" ]]; then
 | 
			
		||||
        BUILD_FROM=esphome/esphome-hassio-base-${BUILD_ARCH}:1.2.1
 | 
			
		||||
        BUILD_FROM=esphome/esphome-hassio-base-${BUILD_ARCH}:1.4.3
 | 
			
		||||
        BUILD_TO=esphome/esphome-hassio-${BUILD_ARCH}
 | 
			
		||||
        DOCKERFILE=docker/Dockerfile.hassio
 | 
			
		||||
      else
 | 
			
		||||
        BUILD_FROM=esphome/esphome-base-${BUILD_ARCH}:1.2.1
 | 
			
		||||
        BUILD_FROM=esphome/esphome-base-${BUILD_ARCH}:1.4.3
 | 
			
		||||
        if [[ "${BUILD_ARCH}" == "amd64" ]]; then
 | 
			
		||||
          BUILD_TO=esphome/esphome
 | 
			
		||||
        else
 | 
			
		||||
@@ -126,7 +126,7 @@ test3:
 | 
			
		||||
  - pip install -e .
 | 
			
		||||
  - pip install twine
 | 
			
		||||
  script:
 | 
			
		||||
  - python setup.py sdist
 | 
			
		||||
  - python setup.py sdist bdist_wheel
 | 
			
		||||
  - twine upload dist/*
 | 
			
		||||
  tags:
 | 
			
		||||
  - docker
 | 
			
		||||
@@ -177,48 +177,48 @@ deploy-beta:pypi:
 | 
			
		||||
.dev-vars: &dev-vars
 | 
			
		||||
  DEV: YES
 | 
			
		||||
 | 
			
		||||
aarch64-beta-docker:
 | 
			
		||||
  <<: *beta
 | 
			
		||||
  variables:
 | 
			
		||||
    BETA: "YES"
 | 
			
		||||
    BUILD_ARCH: aarch64
 | 
			
		||||
    IS_HASSIO: "NO"
 | 
			
		||||
    RELEASE: "YES"
 | 
			
		||||
aarch64-beta-hassio:
 | 
			
		||||
  <<: *beta
 | 
			
		||||
  variables:
 | 
			
		||||
    BETA: "YES"
 | 
			
		||||
    BUILD_ARCH: aarch64
 | 
			
		||||
    IS_HASSIO: "YES"
 | 
			
		||||
    RELEASE: "YES"
 | 
			
		||||
aarch64-dev-docker:
 | 
			
		||||
  <<: *dev
 | 
			
		||||
  variables:
 | 
			
		||||
    BUILD_ARCH: aarch64
 | 
			
		||||
    DEV: "YES"
 | 
			
		||||
    IS_HASSIO: "NO"
 | 
			
		||||
aarch64-dev-hassio:
 | 
			
		||||
  <<: *dev
 | 
			
		||||
  variables:
 | 
			
		||||
    BUILD_ARCH: aarch64
 | 
			
		||||
    DEV: "YES"
 | 
			
		||||
    IS_HASSIO: "YES"
 | 
			
		||||
aarch64-latest-docker:
 | 
			
		||||
  <<: *latest
 | 
			
		||||
  variables:
 | 
			
		||||
    BETA: "YES"
 | 
			
		||||
    BUILD_ARCH: aarch64
 | 
			
		||||
    IS_HASSIO: "NO"
 | 
			
		||||
    LATEST: "YES"
 | 
			
		||||
    RELEASE: "YES"
 | 
			
		||||
aarch64-latest-hassio:
 | 
			
		||||
  <<: *latest
 | 
			
		||||
  variables:
 | 
			
		||||
    BETA: "YES"
 | 
			
		||||
    BUILD_ARCH: aarch64
 | 
			
		||||
    IS_HASSIO: "YES"
 | 
			
		||||
    LATEST: "YES"
 | 
			
		||||
    RELEASE: "YES"
 | 
			
		||||
#aarch64-beta-docker:
 | 
			
		||||
#  <<: *beta
 | 
			
		||||
#  variables:
 | 
			
		||||
#    BETA: "YES"
 | 
			
		||||
#    BUILD_ARCH: aarch64
 | 
			
		||||
#    IS_HASSIO: "NO"
 | 
			
		||||
#    RELEASE: "YES"
 | 
			
		||||
#aarch64-beta-hassio:
 | 
			
		||||
#  <<: *beta
 | 
			
		||||
#  variables:
 | 
			
		||||
#    BETA: "YES"
 | 
			
		||||
#    BUILD_ARCH: aarch64
 | 
			
		||||
#    IS_HASSIO: "YES"
 | 
			
		||||
#    RELEASE: "YES"
 | 
			
		||||
#aarch64-dev-docker:
 | 
			
		||||
#  <<: *dev
 | 
			
		||||
#  variables:
 | 
			
		||||
#    BUILD_ARCH: aarch64
 | 
			
		||||
#    DEV: "YES"
 | 
			
		||||
#    IS_HASSIO: "NO"
 | 
			
		||||
#aarch64-dev-hassio:
 | 
			
		||||
#  <<: *dev
 | 
			
		||||
#  variables:
 | 
			
		||||
#    BUILD_ARCH: aarch64
 | 
			
		||||
#    DEV: "YES"
 | 
			
		||||
#    IS_HASSIO: "YES"
 | 
			
		||||
#aarch64-latest-docker:
 | 
			
		||||
#  <<: *latest
 | 
			
		||||
#  variables:
 | 
			
		||||
#    BETA: "YES"
 | 
			
		||||
#    BUILD_ARCH: aarch64
 | 
			
		||||
#    IS_HASSIO: "NO"
 | 
			
		||||
#    LATEST: "YES"
 | 
			
		||||
#    RELEASE: "YES"
 | 
			
		||||
#aarch64-latest-hassio:
 | 
			
		||||
#  <<: *latest
 | 
			
		||||
#  variables:
 | 
			
		||||
#    BETA: "YES"
 | 
			
		||||
#    BUILD_ARCH: aarch64
 | 
			
		||||
#    IS_HASSIO: "YES"
 | 
			
		||||
#    LATEST: "YES"
 | 
			
		||||
#    RELEASE: "YES"
 | 
			
		||||
amd64-beta-docker:
 | 
			
		||||
  <<: *beta
 | 
			
		||||
  variables:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,6 +1,13 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: python
 | 
			
		||||
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
    - "~/.platformio"
 | 
			
		||||
    - "$TRAVIS_BUILD_DIR/tests/build/test1/.piolibdeps"
 | 
			
		||||
    - "$TRAVIS_BUILD_DIR/tests/build/test2/.piolibdeps"
 | 
			
		||||
    - "$TRAVIS_BUILD_DIR/tests/build/test3/.piolibdeps"
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
  fast_finish: true
 | 
			
		||||
  include:
 | 
			
		||||
@@ -12,7 +19,7 @@ matrix:
 | 
			
		||||
        - pylint esphome
 | 
			
		||||
    - python: "3.5.3"
 | 
			
		||||
      env: TARGET=Lint3.5
 | 
			
		||||
      install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 pillow
 | 
			
		||||
      install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.3.0 pillow
 | 
			
		||||
      script:
 | 
			
		||||
        - flake8 esphome
 | 
			
		||||
        - pylint esphome
 | 
			
		||||
@@ -25,7 +32,7 @@ matrix:
 | 
			
		||||
        - esphome tests/test3.yaml compile
 | 
			
		||||
    #- python: "3.5.3"
 | 
			
		||||
    #  env: TARGET=Test3.5
 | 
			
		||||
    #  install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 pillow
 | 
			
		||||
    #  install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.3.0 pillow
 | 
			
		||||
    #  script:
 | 
			
		||||
    #    - esphome tests/test1.yaml compile
 | 
			
		||||
    #    - esphome tests/test2.yaml compile
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								MANIFEST.in
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								MANIFEST.in
									
									
									
									
									
								
							@@ -1,17 +1,6 @@
 | 
			
		||||
include LICENSE
 | 
			
		||||
include README.md
 | 
			
		||||
include esphome/dashboard/templates/index.html
 | 
			
		||||
include esphome/dashboard/templates/login.html
 | 
			
		||||
include esphome/dashboard/static/ace.js
 | 
			
		||||
include esphome/dashboard/static/esphome.css
 | 
			
		||||
include esphome/dashboard/static/esphome.js
 | 
			
		||||
include esphome/dashboard/static/favicon.ico
 | 
			
		||||
include esphome/dashboard/static/jquery.min.js
 | 
			
		||||
include esphome/dashboard/static/jquery.validate.min.js
 | 
			
		||||
include esphome/dashboard/static/jquery-ui.min.js
 | 
			
		||||
include esphome/dashboard/static/materialize.min.css
 | 
			
		||||
include esphome/dashboard/static/materialize.min.js
 | 
			
		||||
include esphome/dashboard/static/materialize-stepper.min.css
 | 
			
		||||
include esphome/dashboard/static/materialize-stepper.min.js
 | 
			
		||||
include esphome/dashboard/static/mode-yaml.js
 | 
			
		||||
include esphome/dashboard/static/theme-dreamweaver.js
 | 
			
		||||
include esphome/dashboard/static/ext-searchbox.js
 | 
			
		||||
include esphome/dashboard/templates/*.html
 | 
			
		||||
include esphome/dashboard/static/*.js
 | 
			
		||||
include esphome/dashboard/static/*.css
 | 
			
		||||
include esphome/dashboard/static/*.ico
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
ARG BUILD_FROM=esphome/esphome-base-amd64:1.2.1
 | 
			
		||||
ARG BUILD_FROM=esphome/esphome-base-amd64:1.4.3
 | 
			
		||||
FROM ${BUILD_FROM}
 | 
			
		||||
 | 
			
		||||
COPY . .
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
ARG BUILD_FROM=esphome/esphome-hassio-base-amd64:1.2.1
 | 
			
		||||
ARG BUILD_FROM=esphome/esphome-hassio-base-amd64:1.4.3
 | 
			
		||||
FROM ${BUILD_FROM}
 | 
			
		||||
 | 
			
		||||
# Copy root filesystem
 | 
			
		||||
 
 | 
			
		||||
@@ -16,11 +16,11 @@ echo "PWD: $PWD"
 | 
			
		||||
 | 
			
		||||
if [[ ${IS_HASSIO} = "YES" ]]; then
 | 
			
		||||
    docker build \
 | 
			
		||||
      --build-arg "BUILD_FROM=esphome/esphome-hassio-base-${BUILD_ARCH}:1.2.1" \
 | 
			
		||||
      --build-arg "BUILD_FROM=esphome/esphome-hassio-base-${BUILD_ARCH}:1.4.3" \
 | 
			
		||||
      --build-arg "BUILD_VERSION=${CACHE_TAG}" \
 | 
			
		||||
      -t "${IMAGE_NAME}" -f ../docker/Dockerfile.hassio ..
 | 
			
		||||
else
 | 
			
		||||
    docker build \
 | 
			
		||||
      --build-arg "BUILD_FROM=esphome/esphome-base-${BUILD_ARCH}:1.2.1" \
 | 
			
		||||
      --build-arg "BUILD_FROM=esphome/esphome-base-${BUILD_ARCH}:1.4.3" \
 | 
			
		||||
      -t "${IMAGE_NAME}" -f ../docker/Dockerfile ..
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,41 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
#!/usr/bin/with-contenv bashio
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: ESPHome
 | 
			
		||||
# This files check if all user configuration requirements are met
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
# Check SSL requirements, if enabled
 | 
			
		||||
if hass.config.true 'ssl'; then
 | 
			
		||||
    if ! hass.config.has_value 'certfile'; then
 | 
			
		||||
        hass.die 'SSL is enabled, but no certfile was specified.'
 | 
			
		||||
if bashio::config.true 'ssl'; then
 | 
			
		||||
    if ! bashio::config.has_value 'certfile'; then
 | 
			
		||||
        bashio::fatal 'SSL is enabled, but no certfile was specified.'
 | 
			
		||||
        bashio::exit.nok
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! hass.config.has_value 'keyfile'; then
 | 
			
		||||
        hass.die 'SSL is enabled, but no keyfile was specified'
 | 
			
		||||
    if ! bashio::config.has_value 'keyfile'; then
 | 
			
		||||
        bashio::fatal 'SSL is enabled, but no keyfile was specified'
 | 
			
		||||
        bashio::exit.nok
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! hass.file_exists "/ssl/$(hass.config.get 'certfile')"; then
 | 
			
		||||
        if ! hass.file_exists "/ssl/$(hass.config.get 'keyfile')"; then
 | 
			
		||||
 | 
			
		||||
    certfile="/ssl/$(bashio::config 'certfile')"
 | 
			
		||||
    keyfile="/ssl/$(bashio::config 'keyfile')"
 | 
			
		||||
 | 
			
		||||
    if ! bashio::fs.file_exists "${certfile}"; then
 | 
			
		||||
        if ! bashio::fs.file_exists "${keyfile}"; then
 | 
			
		||||
            # Both files are missing, let's print a friendlier error message
 | 
			
		||||
            text="You enabled encrypted connections using the \"ssl\": true option.
 | 
			
		||||
            However, the SSL files \"$(hass.config.get 'certfile')\" and \"$(hass.config.get 'keyfile')\"
 | 
			
		||||
            were not found. If you're using Hass.io on your local network and don't want
 | 
			
		||||
            to encrypt connections to the ESPHome dashboard, you can manually disable
 | 
			
		||||
            SSL by setting \"ssl\" to false."
 | 
			
		||||
            hass.die "${text}"
 | 
			
		||||
            bashio::log.fatal 'You enabled encrypted connections using the "ssl": true option.'
 | 
			
		||||
            bashio::log.fatal "However, the SSL files '${certfile}' and '${keyfile}'"
 | 
			
		||||
            bashio::log.fatal "were not found. If you're using Hass.io on your local network and don't want"
 | 
			
		||||
            bashio::log.fatal 'to encrypt connections to the ESPHome dashboard, you can manually disable'
 | 
			
		||||
            bashio::log.fatal 'SSL by setting "ssl" to false."'
 | 
			
		||||
            bashio::exit.nok
 | 
			
		||||
        fi
 | 
			
		||||
        hass.die 'The configured certfile is not found'
 | 
			
		||||
        bashio::log.fatal "The configured certfile '${certfile}' was not found."
 | 
			
		||||
        bashio::exit.nok
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! hass.file_exists "/ssl/$(hass.config.get 'keyfile')"; then
 | 
			
		||||
        hass.die 'The configured keyfile is not found'
 | 
			
		||||
    if ! bashio::fs.file_exists "/ssl/$(bashio::config 'keyfile')"; then
 | 
			
		||||
        bashio::log.fatal "The configured keyfile '${keyfile}' was not found."
 | 
			
		||||
        bashio::exit.nok
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
#!/usr/bin/with-contenv bashio
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: ESPHome
 | 
			
		||||
# Configures NGINX for use with ESPHome
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
declare certfile
 | 
			
		||||
declare keyfile
 | 
			
		||||
@@ -13,16 +11,16 @@ declare port
 | 
			
		||||
mkdir -p /var/log/nginx
 | 
			
		||||
 | 
			
		||||
# Enable SSL
 | 
			
		||||
if hass.config.true 'ssl'; then
 | 
			
		||||
if bashio::config.true 'ssl'; then
 | 
			
		||||
    rm /etc/nginx/nginx.conf
 | 
			
		||||
    mv /etc/nginx/nginx-ssl.conf /etc/nginx/nginx.conf
 | 
			
		||||
 | 
			
		||||
    certfile=$(hass.config.get 'certfile')
 | 
			
		||||
    keyfile=$(hass.config.get 'keyfile')
 | 
			
		||||
    certfile=$(bashio::config 'certfile')
 | 
			
		||||
    keyfile=$(bashio::config 'keyfile')
 | 
			
		||||
 | 
			
		||||
    sed -i "s/%%certfile%%/${certfile}/g" /etc/nginx/nginx.conf
 | 
			
		||||
    sed -i "s/%%keyfile%%/${keyfile}/g" /etc/nginx/nginx.conf
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
port=$(hass.config.get 'port')
 | 
			
		||||
port=$(bashio::config 'port')
 | 
			
		||||
sed -i "s/%%port%%/${port}/g" /etc/nginx/nginx.conf
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,15 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
#!/usr/bin/with-contenv bashio
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: ESPHome
 | 
			
		||||
# This files installs the user ESPHome version if specified
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
declare esphome_version
 | 
			
		||||
 | 
			
		||||
if hass.config.has_value 'esphome_version'; then
 | 
			
		||||
    esphome_version=$(hass.config.get 'esphome_version')
 | 
			
		||||
    pip2 install --no-cache-dir --no-binary :all: "https://github.com/esphome/esphome/archive/${esphome_version}.zip"
 | 
			
		||||
if bashio::config.has_value 'esphome_version'; then
 | 
			
		||||
    esphome_version=$(bashio::config 'esphome_version')
 | 
			
		||||
    full_url="https://github.com/esphome/esphome/archive/${esphome_version}.zip"
 | 
			
		||||
    bashio::log.info "Installing esphome version '${esphome_version}' (${full_url})..."
 | 
			
		||||
    pip2 install --no-cache-dir --no-binary :all: "${full_url}" \
 | 
			
		||||
      || bashio::exit.nok "Failed installing esphome pinned version."
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
#!/usr/bin/with-contenv bashio
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: ESPHome
 | 
			
		||||
# This files migrates the esphome config directory from the old path
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
if [[ ! -d /config/esphome && -d /config/esphomeyaml ]]; then
 | 
			
		||||
    echo "Moving config directory from /config/esphomeyaml to /config/esphome"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,26 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
#!/usr/bin/with-contenv bashio
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: ESPHome
 | 
			
		||||
# Runs the ESPHome dashboard
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
if hass.config.true 'leave_front_door_open'; then
 | 
			
		||||
export ESPHOME_IS_HASSIO=true
 | 
			
		||||
 | 
			
		||||
if bashio::config.true 'leave_front_door_open'; then
 | 
			
		||||
    export DISABLE_HA_AUTHENTICATION=true
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
hass.log.info "Starting ESPHome dashboard..."
 | 
			
		||||
if bashio::config.true 'streamer_mode'; then
 | 
			
		||||
    export ESPHOME_STREAMER_MODE=true
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if bashio::config.true 'status_use_ping'; then
 | 
			
		||||
    export ESPHOME_DASHBOARD_USE_PING=true
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if bashio::config.has_value 'relative_url'; then
 | 
			
		||||
    export ESPHOME_DASHBOARD_RELATIVE_URL=$(bashio::config 'relative_url')
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
bashio::log.info "Starting ESPHome dashboard..."
 | 
			
		||||
exec esphome /config/esphome dashboard --socket /var/run/esphome.sock --hassio
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
#!/usr/bin/with-contenv bashio
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: ESPHome
 | 
			
		||||
# Runs the NGINX proxy
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
hass.log.info "Starting NGINX..."
 | 
			
		||||
bashio::log.info "Starting NGINX..."
 | 
			
		||||
exec nginx -g "daemon off;"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
from __future__ import print_function
 | 
			
		||||
 | 
			
		||||
import argparse
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
@@ -17,9 +16,9 @@ from esphome.core import CORE, EsphomeError
 | 
			
		||||
from esphome.cpp_generator import Expression, RawStatement, add, statement
 | 
			
		||||
from esphome.helpers import color, indent
 | 
			
		||||
from esphome.py_compat import IS_PY2, safe_input, text_type
 | 
			
		||||
from esphome.storage_json import StorageJSON, esphome_storage_path, \
 | 
			
		||||
    start_update_check_thread, storage_path
 | 
			
		||||
from esphome.util import run_external_command, run_external_process, safe_print
 | 
			
		||||
from esphome.storage_json import StorageJSON, storage_path
 | 
			
		||||
from esphome.util import run_external_command, run_external_process, safe_print, \
 | 
			
		||||
    is_dev_esphome_version
 | 
			
		||||
 | 
			
		||||
_LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
@@ -157,17 +156,21 @@ def write_cpp(config):
 | 
			
		||||
 | 
			
		||||
def compile_program(args, config):
 | 
			
		||||
    _LOGGER.info("Compiling app...")
 | 
			
		||||
    update_check = not os.getenv('ESPHOME_NO_UPDATE_CHECK', '')
 | 
			
		||||
    if update_check:
 | 
			
		||||
        thread = start_update_check_thread(esphome_storage_path(CORE.config_dir))
 | 
			
		||||
    rc = platformio_api.run_compile(config, args.verbose)
 | 
			
		||||
    if update_check:
 | 
			
		||||
        thread.join()
 | 
			
		||||
    if rc != 0 and CORE.is_dev_esphome_core_version and not is_dev_esphome_version():
 | 
			
		||||
        _LOGGER.warning("You're using 'esphome_core_version: dev' but not using the "
 | 
			
		||||
                        "dev version of the ESPHome tool.")
 | 
			
		||||
        _LOGGER.warning("Expect compile errors if these versions are out of sync.")
 | 
			
		||||
        _LOGGER.warning("Please install the dev version of ESPHome too when using "
 | 
			
		||||
                        "'esphome_core_version: dev'.")
 | 
			
		||||
        _LOGGER.warning(" - Hass.io: Install 'ESPHome (dev)' addon")
 | 
			
		||||
        _LOGGER.warning(" - Docker: docker run [...] esphome/esphome:dev [...]")
 | 
			
		||||
        _LOGGER.warning(" - PIP: pip install -U https://github.com/esphome/esphome/archive/dev.zip")
 | 
			
		||||
    return rc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def upload_using_esptool(config, port):
 | 
			
		||||
    path = os.path.join(CORE.build_path, '.pioenvs', CORE.name, 'firmware.bin')
 | 
			
		||||
    path = CORE.firmware_bin
 | 
			
		||||
    cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
 | 
			
		||||
           '--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path]
 | 
			
		||||
 | 
			
		||||
@@ -344,28 +347,6 @@ def command_clean(args, config):
 | 
			
		||||
    return 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def command_hass_config(args, config):
 | 
			
		||||
    from esphome.components import mqtt as mqtt_component
 | 
			
		||||
 | 
			
		||||
    _LOGGER.info("This is what you should put in your Home Assistant YAML configuration.")
 | 
			
		||||
    _LOGGER.info("Please note this is only necessary if you're not using MQTT discovery.")
 | 
			
		||||
    data = mqtt_component.GenerateHassConfigData(config)
 | 
			
		||||
    hass_config = OrderedDict()
 | 
			
		||||
    for domain, component, conf in iter_components(config):
 | 
			
		||||
        if not hasattr(component, 'to_hass_config'):
 | 
			
		||||
            continue
 | 
			
		||||
        func = getattr(component, 'to_hass_config')
 | 
			
		||||
        ret = func(data, conf)
 | 
			
		||||
        if not isinstance(ret, (list, tuple)):
 | 
			
		||||
            ret = [ret]
 | 
			
		||||
        ret = [x for x in ret if x is not None]
 | 
			
		||||
        domain_conf = hass_config.setdefault(domain.split('.')[0], [])
 | 
			
		||||
        domain_conf += ret
 | 
			
		||||
 | 
			
		||||
    safe_print(yaml_util.dump(hass_config))
 | 
			
		||||
    return 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def command_dashboard(args):
 | 
			
		||||
    from esphome.dashboard import dashboard
 | 
			
		||||
 | 
			
		||||
@@ -387,7 +368,6 @@ POST_CONFIG_ACTIONS = {
 | 
			
		||||
    'clean-mqtt': command_clean_mqtt,
 | 
			
		||||
    'mqtt-fingerprint': command_mqtt_fingerprint,
 | 
			
		||||
    'clean': command_clean,
 | 
			
		||||
    'hass-config': command_hass_config,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -467,10 +447,6 @@ def parse_args(argv):
 | 
			
		||||
    dashboard.add_argument("--socket",
 | 
			
		||||
                           help="Make the dashboard serve under a unix socket", type=str)
 | 
			
		||||
 | 
			
		||||
    subparsers.add_parser('hass-config',
 | 
			
		||||
                          help="Dump the configuration entries that should be added "
 | 
			
		||||
                               "to Home Assistant when not using MQTT discovery.")
 | 
			
		||||
 | 
			
		||||
    return parser.parse_args(argv[1:])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
# Generated by the protocol buffer compiler.  DO NOT EDIT!
 | 
			
		||||
# source: api.proto
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,9 @@ import copy
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \
 | 
			
		||||
    CONF_BELOW, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, CONF_ELSE, CONF_ID, CONF_IF, \
 | 
			
		||||
    CONF_LAMBDA, CONF_OR, CONF_RANGE, CONF_THEN, CONF_TRIGGER_ID, CONF_WHILE, CONF_WAIT_UNTIL
 | 
			
		||||
from esphome.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, CONF_BELOW, \
 | 
			
		||||
    CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, CONF_ELSE, CONF_ID, CONF_IF, CONF_LAMBDA, \
 | 
			
		||||
    CONF_OR, CONF_RANGE, CONF_THEN, CONF_TRIGGER_ID, CONF_WAIT_UNTIL, CONF_WHILE
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, TemplateArguments, add, get_variable, \
 | 
			
		||||
    process_lambda, templatable
 | 
			
		||||
@@ -48,7 +48,7 @@ def validate_recursive_condition(value):
 | 
			
		||||
                              u"".format(key, key2), path)
 | 
			
		||||
        validator = CONDITION_REGISTRY[key][0]
 | 
			
		||||
        try:
 | 
			
		||||
            condition = validator(item[key])
 | 
			
		||||
            condition = validator(item[key] or {})
 | 
			
		||||
        except vol.Invalid as err:
 | 
			
		||||
            err.prepend(path)
 | 
			
		||||
            raise err
 | 
			
		||||
@@ -83,7 +83,7 @@ def validate_recursive_action(value):
 | 
			
		||||
                              u"".format(key, key2), path)
 | 
			
		||||
        validator = ACTION_REGISTRY[key][0]
 | 
			
		||||
        try:
 | 
			
		||||
            action = validator(item[key])
 | 
			
		||||
            action = validator(item[key] or {})
 | 
			
		||||
        except vol.Invalid as err:
 | 
			
		||||
            err.prepend(path)
 | 
			
		||||
            raise err
 | 
			
		||||
@@ -131,7 +131,7 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
 | 
			
		||||
 | 
			
		||||
                # Next try as a sequence of automations
 | 
			
		||||
                try:
 | 
			
		||||
                    return vol.Schema([schema])(value)
 | 
			
		||||
                    return cv.Schema([schema])(value)
 | 
			
		||||
                except vol.Invalid as err2:
 | 
			
		||||
                    if 'Unable to find action' in str(err):
 | 
			
		||||
                        raise err2
 | 
			
		||||
@@ -146,7 +146,7 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
 | 
			
		||||
    def validator(value):
 | 
			
		||||
        value = validator_(value)
 | 
			
		||||
        if extra_validators is not None:
 | 
			
		||||
            value = vol.Schema([extra_validators])(value)
 | 
			
		||||
            value = cv.Schema([extra_validators])(value)
 | 
			
		||||
        if single:
 | 
			
		||||
            if len(value) != 1:
 | 
			
		||||
                raise vol.Invalid("Cannot have more than 1 automation for templates")
 | 
			
		||||
@@ -156,10 +156,9 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
 | 
			
		||||
    return validator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
AUTOMATION_SCHEMA = vol.Schema({
 | 
			
		||||
AUTOMATION_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(Trigger),
 | 
			
		||||
    cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(Automation),
 | 
			
		||||
    vol.Optional(CONF_IF): validate_recursive_condition,
 | 
			
		||||
    vol.Required(CONF_THEN): validate_recursive_action,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -167,8 +166,8 @@ AND_CONDITION_SCHEMA = validate_recursive_condition
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_AND, AND_CONDITION_SCHEMA)
 | 
			
		||||
def and_condition_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config, arg_type):
 | 
			
		||||
def and_condition_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for conditions in build_conditions(config, template_arg, args):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = AndCondition.new(template_arg, conditions)
 | 
			
		||||
    type = AndCondition.template(template_arg)
 | 
			
		||||
@@ -179,33 +178,33 @@ OR_CONDITION_SCHEMA = validate_recursive_condition
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_OR, OR_CONDITION_SCHEMA)
 | 
			
		||||
def or_condition_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config, arg_type):
 | 
			
		||||
def or_condition_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for conditions in build_conditions(config, template_arg, args):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = OrCondition.new(template_arg, conditions)
 | 
			
		||||
    type = OrCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RANGE_CONDITION_SCHEMA = vol.All(vol.Schema({
 | 
			
		||||
RANGE_CONDITION_SCHEMA = vol.All(cv.Schema({
 | 
			
		||||
    vol.Optional(CONF_ABOVE): cv.templatable(cv.float_),
 | 
			
		||||
    vol.Optional(CONF_BELOW): cv.templatable(cv.float_),
 | 
			
		||||
}), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_RANGE, RANGE_CONDITION_SCHEMA)
 | 
			
		||||
def range_condition_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config, arg_type):
 | 
			
		||||
def range_condition_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for conditions in build_conditions(config, template_arg, args):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = RangeCondition.new(template_arg, conditions)
 | 
			
		||||
    type = RangeCondition.template(template_arg)
 | 
			
		||||
    condition = Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
    if CONF_ABOVE in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_ABOVE], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_ABOVE], args, float_):
 | 
			
		||||
            yield
 | 
			
		||||
        condition.set_min(template_)
 | 
			
		||||
    if CONF_BELOW in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_BELOW], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_BELOW], args, float_):
 | 
			
		||||
            yield
 | 
			
		||||
        condition.set_max(template_)
 | 
			
		||||
    yield condition
 | 
			
		||||
@@ -215,11 +214,11 @@ DELAY_ACTION_SCHEMA = cv.templatable(cv.positive_time_period_milliseconds)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_DELAY, DELAY_ACTION_SCHEMA)
 | 
			
		||||
def delay_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def delay_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    rhs = App.register_component(DelayAction.new(template_arg))
 | 
			
		||||
    type = DelayAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    for template_ in templatable(config, arg_type, uint32):
 | 
			
		||||
    for template_ in templatable(config, args, uint32):
 | 
			
		||||
        yield
 | 
			
		||||
    add(action.set_delay(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
@@ -233,44 +232,44 @@ IF_ACTION_SCHEMA = vol.All({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_IF, IF_ACTION_SCHEMA)
 | 
			
		||||
def if_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], arg_type):
 | 
			
		||||
def if_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], template_arg, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = IfAction.new(template_arg, conditions)
 | 
			
		||||
    type = IfAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    if CONF_THEN in config:
 | 
			
		||||
        for actions in build_actions(config[CONF_THEN], arg_type):
 | 
			
		||||
        for actions in build_actions(config[CONF_THEN], template_arg, args):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.add_then(actions))
 | 
			
		||||
    if CONF_ELSE in config:
 | 
			
		||||
        for actions in build_actions(config[CONF_ELSE], arg_type):
 | 
			
		||||
        for actions in build_actions(config[CONF_ELSE], template_arg, args):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.add_else(actions))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
WHILE_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
WHILE_ACTION_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_CONDITION): validate_recursive_condition,
 | 
			
		||||
    vol.Required(CONF_THEN): validate_recursive_action,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_WHILE, WHILE_ACTION_SCHEMA)
 | 
			
		||||
def while_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], arg_type):
 | 
			
		||||
def while_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], template_arg, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = WhileAction.new(template_arg, conditions)
 | 
			
		||||
    type = WhileAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    for actions in build_actions(config[CONF_THEN], arg_type):
 | 
			
		||||
    for actions in build_actions(config[CONF_THEN], template_arg, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.add_then(actions))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_wait_until(value):
 | 
			
		||||
    schema = vol.Schema({
 | 
			
		||||
    schema = cv.Schema({
 | 
			
		||||
        vol.Required(CONF_CONDITION): validate_recursive_condition
 | 
			
		||||
    })
 | 
			
		||||
    if isinstance(value, dict) and CONF_CONDITION in value:
 | 
			
		||||
@@ -282,8 +281,8 @@ WAIT_UNTIL_ACTION_SCHEMA = validate_wait_until
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_WAIT_UNTIL, WAIT_UNTIL_ACTION_SCHEMA)
 | 
			
		||||
def wait_until_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], arg_type):
 | 
			
		||||
def wait_until_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], template_arg, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = WaitUntilAction.new(template_arg, conditions)
 | 
			
		||||
    type = WaitUntilAction.template(template_arg)
 | 
			
		||||
@@ -296,8 +295,8 @@ LAMBDA_ACTION_SCHEMA = cv.lambda_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_LAMBDA, LAMBDA_ACTION_SCHEMA)
 | 
			
		||||
def lambda_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for lambda_ in process_lambda(config, [(arg_type, 'x')], return_type=void):
 | 
			
		||||
def lambda_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for lambda_ in process_lambda(config, args, return_type=void):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = LambdaAction.new(template_arg, lambda_)
 | 
			
		||||
    type = LambdaAction.template(template_arg)
 | 
			
		||||
@@ -308,8 +307,8 @@ LAMBDA_CONDITION_SCHEMA = cv.lambda_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_LAMBDA, LAMBDA_CONDITION_SCHEMA)
 | 
			
		||||
def lambda_condition_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
    for lambda_ in process_lambda(config, [(arg_type, 'x')], return_type=bool_):
 | 
			
		||||
def lambda_condition_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for lambda_ in process_lambda(config, args, return_type=bool_):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = LambdaCondition.new(template_arg, lambda_)
 | 
			
		||||
    type = LambdaCondition.template(template_arg)
 | 
			
		||||
@@ -323,7 +322,7 @@ COMPONENT_UPDATE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_COMPONENT_UPDATE, COMPONENT_UPDATE_ACTION_SCHEMA)
 | 
			
		||||
def component_update_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def component_update_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = UpdateComponentAction.new(template_arg, var)
 | 
			
		||||
@@ -331,61 +330,55 @@ def component_update_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_action(full_config, arg_type):
 | 
			
		||||
def build_action(full_config, template_arg, args):
 | 
			
		||||
    action_id = full_config[CONF_ACTION_ID]
 | 
			
		||||
    key, config = next((k, v) for k, v in full_config.items() if k in ACTION_REGISTRY)
 | 
			
		||||
 | 
			
		||||
    builder = ACTION_REGISTRY[key][1]
 | 
			
		||||
    template_arg = TemplateArguments(arg_type)
 | 
			
		||||
    for result in builder(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for result in builder(config, action_id, template_arg, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    yield result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_actions(config, arg_type):
 | 
			
		||||
def build_actions(config, templ, arg_type):
 | 
			
		||||
    actions = []
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for action in build_action(conf, arg_type):
 | 
			
		||||
        for action in build_action(conf, templ, arg_type):
 | 
			
		||||
            yield None
 | 
			
		||||
        actions.append(action)
 | 
			
		||||
    yield actions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_condition(full_config, arg_type):
 | 
			
		||||
def build_condition(full_config, template_arg, args):
 | 
			
		||||
    action_id = full_config[CONF_CONDITION_ID]
 | 
			
		||||
    key, config = next((k, v) for k, v in full_config.items() if k in CONDITION_REGISTRY)
 | 
			
		||||
 | 
			
		||||
    builder = CONDITION_REGISTRY[key][1]
 | 
			
		||||
    template_arg = TemplateArguments(arg_type)
 | 
			
		||||
    for result in builder(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for result in builder(config, action_id, template_arg, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    yield result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_conditions(config, arg_type):
 | 
			
		||||
def build_conditions(config, templ, args):
 | 
			
		||||
    conditions = []
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for condition in build_condition(conf, arg_type):
 | 
			
		||||
        for condition in build_condition(conf, templ, args):
 | 
			
		||||
            yield None
 | 
			
		||||
        conditions.append(condition)
 | 
			
		||||
    yield conditions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_automation_(trigger, arg_type, config):
 | 
			
		||||
    rhs = App.make_automation(TemplateArguments(arg_type), trigger)
 | 
			
		||||
    type = Automation.template(arg_type)
 | 
			
		||||
def build_automation_(trigger, args, config):
 | 
			
		||||
    arg_types = [arg[0] for arg in args]
 | 
			
		||||
    templ = TemplateArguments(*arg_types)
 | 
			
		||||
    rhs = App.make_automation(templ, trigger)
 | 
			
		||||
    type = Automation.template(templ)
 | 
			
		||||
    obj = Pvariable(config[CONF_AUTOMATION_ID], rhs, type=type)
 | 
			
		||||
    if CONF_IF in config:
 | 
			
		||||
        conditions = None
 | 
			
		||||
        for conditions in build_conditions(config[CONF_IF], arg_type):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(obj.add_conditions(conditions))
 | 
			
		||||
    actions = None
 | 
			
		||||
    for actions in build_actions(config[CONF_THEN], arg_type):
 | 
			
		||||
    for actions in build_actions(config[CONF_THEN], templ, args):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(obj.add_actions(actions))
 | 
			
		||||
    yield obj
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_automation(trigger, arg_type, config):
 | 
			
		||||
    CORE.add_job(build_automation_, trigger, arg_type, config)
 | 
			
		||||
def build_automations(trigger, args, config):
 | 
			
		||||
    CORE.add_job(build_automation_, trigger, args, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
ADS1115Component = sensor.sensor_ns.class_('ADS1115Component', Component, i2c.I2CDevice)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(ADS1115Component),
 | 
			
		||||
    vol.Required(CONF_ADDRESS): cv.i2c_address,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ MULTI_CONF = True
 | 
			
		||||
CONF_APDS9960_ID = 'apds9960_id'
 | 
			
		||||
APDS9960 = sensor.sensor_ns.class_('APDS9960', PollingComponent, i2c.I2CDevice)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(APDS9960),
 | 
			
		||||
    vol.Optional(CONF_ADDRESS): cv.i2c_address,
 | 
			
		||||
    vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,52 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome.automation import ACTION_REGISTRY
 | 
			
		||||
from esphome import automation
 | 
			
		||||
from esphome.automation import ACTION_REGISTRY, CONDITION_REGISTRY, Condition
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_DATA, CONF_DATA_TEMPLATE, CONF_ID, CONF_PASSWORD, CONF_PORT, \
 | 
			
		||||
    CONF_REBOOT_TIMEOUT, CONF_SERVICE, CONF_VARIABLES
 | 
			
		||||
    CONF_REBOOT_TIMEOUT, CONF_SERVICE, CONF_VARIABLES, CONF_SERVICES, CONF_TRIGGER_ID
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda
 | 
			
		||||
from esphome.cpp_helpers import setup_component
 | 
			
		||||
from esphome.cpp_types import Action, App, Component, StoringController, esphome_ns
 | 
			
		||||
from esphome.cpp_types import Action, App, Component, StoringController, esphome_ns, Trigger, \
 | 
			
		||||
    bool_, int32, float_, std_string
 | 
			
		||||
 | 
			
		||||
api_ns = esphome_ns.namespace('api')
 | 
			
		||||
APIServer = api_ns.class_('APIServer', Component, StoringController)
 | 
			
		||||
HomeAssistantServiceCallAction = api_ns.class_('HomeAssistantServiceCallAction', Action)
 | 
			
		||||
KeyValuePair = api_ns.class_('KeyValuePair')
 | 
			
		||||
TemplatableKeyValuePair = api_ns.class_('TemplatableKeyValuePair')
 | 
			
		||||
APIConnectedCondition = api_ns.class_('APIConnectedCondition', Condition)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
UserService = api_ns.class_('UserService', Trigger)
 | 
			
		||||
ServiceTypeArgument = api_ns.class_('ServiceTypeArgument')
 | 
			
		||||
ServiceArgType = api_ns.enum('ServiceArgType')
 | 
			
		||||
SERVICE_ARG_TYPES = {
 | 
			
		||||
    'bool': ServiceArgType.SERVICE_ARG_TYPE_BOOL,
 | 
			
		||||
    'int': ServiceArgType.SERVICE_ARG_TYPE_INT,
 | 
			
		||||
    'float': ServiceArgType.SERVICE_ARG_TYPE_FLOAT,
 | 
			
		||||
    'string': ServiceArgType.SERVICE_ARG_TYPE_STRING,
 | 
			
		||||
}
 | 
			
		||||
SERVICE_ARG_NATIVE_TYPES = {
 | 
			
		||||
    'bool': bool_,
 | 
			
		||||
    'int': int32,
 | 
			
		||||
    'float': float_,
 | 
			
		||||
    'string': std_string,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(APIServer),
 | 
			
		||||
    vol.Optional(CONF_PORT, default=6053): cv.port,
 | 
			
		||||
    vol.Optional(CONF_PASSWORD, default=''): cv.string_strict,
 | 
			
		||||
    vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_SERVICES): automation.validate_automation({
 | 
			
		||||
        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(UserService),
 | 
			
		||||
        vol.Required(CONF_SERVICE): cv.valid_name,
 | 
			
		||||
        vol.Optional(CONF_VARIABLES, default={}): cv.Schema({
 | 
			
		||||
            cv.validate_id_name: cv.one_of(*SERVICE_ARG_TYPES, lower=True),
 | 
			
		||||
        }),
 | 
			
		||||
    }),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -34,6 +61,21 @@ def to_code(config):
 | 
			
		||||
    if CONF_REBOOT_TIMEOUT in config:
 | 
			
		||||
        add(api.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_SERVICES, []):
 | 
			
		||||
        template_args = []
 | 
			
		||||
        func_args = []
 | 
			
		||||
        service_type_args = []
 | 
			
		||||
        for name, var_ in conf[CONF_VARIABLES].items():
 | 
			
		||||
            native = SERVICE_ARG_NATIVE_TYPES[var_]
 | 
			
		||||
            template_args.append(native)
 | 
			
		||||
            func_args.append((native, name))
 | 
			
		||||
            service_type_args.append(ServiceTypeArgument(name, SERVICE_ARG_TYPES[var_]))
 | 
			
		||||
        func = api.make_user_service_trigger.template(*template_args)
 | 
			
		||||
        rhs = func(conf[CONF_SERVICE], service_type_args)
 | 
			
		||||
        type_ = UserService.template(*template_args)
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs, type=type_)
 | 
			
		||||
        automation.build_automations(trigger, func_args, conf)
 | 
			
		||||
 | 
			
		||||
    setup_component(api, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -42,34 +84,34 @@ BUILD_FLAGS = '-DUSE_API'
 | 
			
		||||
 | 
			
		||||
def lib_deps(config):
 | 
			
		||||
    if CORE.is_esp32:
 | 
			
		||||
        return 'AsyncTCP@1.0.1'
 | 
			
		||||
        return 'AsyncTCP@1.0.3'
 | 
			
		||||
    if CORE.is_esp8266:
 | 
			
		||||
        return 'ESPAsyncTCP@1.1.3'
 | 
			
		||||
        return 'ESPAsyncTCP@1.2.0'
 | 
			
		||||
    raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_HOMEASSISTANT_SERVICE = 'homeassistant.service'
 | 
			
		||||
HOMEASSISTANT_SERVIC_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
HOMEASSISTANT_SERVIC_ACTION_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.use_variable_id(APIServer),
 | 
			
		||||
    vol.Required(CONF_SERVICE): cv.string,
 | 
			
		||||
    vol.Optional(CONF_DATA): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_DATA): cv.Schema({
 | 
			
		||||
        cv.string: cv.string,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_DATA_TEMPLATE): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_DATA_TEMPLATE): cv.Schema({
 | 
			
		||||
        cv.string: cv.string,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_VARIABLES): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_VARIABLES): cv.Schema({
 | 
			
		||||
        cv.string: cv.lambda_,
 | 
			
		||||
    }),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_HOMEASSISTANT_SERVICE, HOMEASSISTANT_SERVIC_ACTION_SCHEMA)
 | 
			
		||||
def homeassistant_service_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def homeassistant_service_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_home_assistant_service_call_action(template_arg)
 | 
			
		||||
    type = HomeAssistantServiceCallAction.template(arg_type)
 | 
			
		||||
    type = HomeAssistantServiceCallAction.template(template_arg)
 | 
			
		||||
    act = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    add(act.set_service(config[CONF_SERVICE]))
 | 
			
		||||
    if CONF_DATA in config:
 | 
			
		||||
@@ -86,3 +128,14 @@ def homeassistant_service_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
            datas.append(TemplatableKeyValuePair(key, value_))
 | 
			
		||||
        add(act.set_variables(datas))
 | 
			
		||||
    yield act
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_API_CONNECTED = 'api.connected'
 | 
			
		||||
API_CONNECTED_CONDITION_SCHEMA = cv.Schema({})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_API_CONNECTED, API_CONNECTED_CONDITION_SCHEMA)
 | 
			
		||||
def api_connected_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    rhs = APIConnectedCondition.new(template_arg)
 | 
			
		||||
    type = APIConnectedCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,10 @@ from esphome.const import CONF_DELAYED_OFF, CONF_DELAYED_ON, CONF_DEVICE_CLASS,
 | 
			
		||||
    CONF_HEARTBEAT, CONF_ID, CONF_INTERNAL, CONF_INVALID_COOLDOWN, CONF_INVERT, CONF_INVERTED, \
 | 
			
		||||
    CONF_LAMBDA, CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, \
 | 
			
		||||
    CONF_ON_DOUBLE_CLICK, CONF_ON_MULTI_CLICK, CONF_ON_PRESS, CONF_ON_RELEASE, CONF_ON_STATE, \
 | 
			
		||||
    CONF_STATE, CONF_TIMING, CONF_TRIGGER_ID
 | 
			
		||||
    CONF_STATE, CONF_TIMING, CONF_TRIGGER_ID, CONF_FOR
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, StructInitializer, add, get_variable, process_lambda
 | 
			
		||||
from esphome.cpp_types import App, Component, Nameable, NoArg, Trigger, bool_, esphome_ns, optional
 | 
			
		||||
from esphome.cpp_types import App, Component, Nameable, Trigger, bool_, esphome_ns, optional
 | 
			
		||||
from esphome.py_compat import string_types
 | 
			
		||||
 | 
			
		||||
DEVICE_CLASSES = [
 | 
			
		||||
@@ -32,11 +32,11 @@ BinarySensorPtr = BinarySensor.operator('ptr')
 | 
			
		||||
MQTTBinarySensorComponent = binary_sensor_ns.class_('MQTTBinarySensorComponent', mqtt.MQTTComponent)
 | 
			
		||||
 | 
			
		||||
# Triggers
 | 
			
		||||
PressTrigger = binary_sensor_ns.class_('PressTrigger', Trigger.template(NoArg))
 | 
			
		||||
ReleaseTrigger = binary_sensor_ns.class_('ReleaseTrigger', Trigger.template(NoArg))
 | 
			
		||||
ClickTrigger = binary_sensor_ns.class_('ClickTrigger', Trigger.template(NoArg))
 | 
			
		||||
DoubleClickTrigger = binary_sensor_ns.class_('DoubleClickTrigger', Trigger.template(NoArg))
 | 
			
		||||
MultiClickTrigger = binary_sensor_ns.class_('MultiClickTrigger', Trigger.template(NoArg), Component)
 | 
			
		||||
PressTrigger = binary_sensor_ns.class_('PressTrigger', Trigger.template())
 | 
			
		||||
ReleaseTrigger = binary_sensor_ns.class_('ReleaseTrigger', Trigger.template())
 | 
			
		||||
ClickTrigger = binary_sensor_ns.class_('ClickTrigger', Trigger.template())
 | 
			
		||||
DoubleClickTrigger = binary_sensor_ns.class_('DoubleClickTrigger', Trigger.template())
 | 
			
		||||
MultiClickTrigger = binary_sensor_ns.class_('MultiClickTrigger', Trigger.template(), Component)
 | 
			
		||||
MultiClickTriggerEvent = binary_sensor_ns.struct('MultiClickTriggerEvent')
 | 
			
		||||
StateTrigger = binary_sensor_ns.class_('StateTrigger', Trigger.template(bool_))
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +62,7 @@ FILTERS_SCHEMA = cv.ensure_list({
 | 
			
		||||
    vol.Optional(CONF_HEARTBEAT): cv.invalid("The heartbeat filter has been removed in 1.11.0"),
 | 
			
		||||
}, cv.has_exactly_one_key(*FILTER_KEYS))
 | 
			
		||||
 | 
			
		||||
MULTI_CLICK_TIMING_SCHEMA = vol.Schema({
 | 
			
		||||
MULTI_CLICK_TIMING_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Optional(CONF_STATE): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds,
 | 
			
		||||
@@ -234,23 +234,23 @@ def setup_binary_sensor_core_(binary_sensor_var, config):
 | 
			
		||||
    for conf in config.get(CONF_ON_PRESS, []):
 | 
			
		||||
        rhs = binary_sensor_var.make_press_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_RELEASE, []):
 | 
			
		||||
        rhs = binary_sensor_var.make_release_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_CLICK, []):
 | 
			
		||||
        rhs = binary_sensor_var.make_click_trigger(conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH])
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_DOUBLE_CLICK, []):
 | 
			
		||||
        rhs = binary_sensor_var.make_double_click_trigger(conf[CONF_MIN_LENGTH],
 | 
			
		||||
                                                          conf[CONF_MAX_LENGTH])
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_MULTI_CLICK, []):
 | 
			
		||||
        timings = []
 | 
			
		||||
@@ -265,12 +265,12 @@ def setup_binary_sensor_core_(binary_sensor_var, config):
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        if CONF_INVALID_COOLDOWN in conf:
 | 
			
		||||
            add(trigger.set_invalid_cooldown(conf[CONF_INVALID_COOLDOWN]))
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_STATE, []):
 | 
			
		||||
        rhs = binary_sensor_var.make_state_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, bool_, conf)
 | 
			
		||||
        automation.build_automations(trigger, [(bool_, 'x')], conf)
 | 
			
		||||
 | 
			
		||||
    setup_mqtt_component(binary_sensor_var.Pget_mqtt(), config)
 | 
			
		||||
 | 
			
		||||
@@ -287,43 +287,35 @@ def register_binary_sensor(var, config):
 | 
			
		||||
    CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def core_to_hass_config(data, config):
 | 
			
		||||
    ret = mqtt.build_hass_config(data, 'binary_sensor', config,
 | 
			
		||||
                                 include_state=True, include_command=False)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    if CONF_DEVICE_CLASS in config:
 | 
			
		||||
        ret['device_class'] = config[CONF_DEVICE_CLASS]
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
CONF_BINARY_SENSOR_IS_ON = 'binary_sensor.is_on'
 | 
			
		||||
BINARY_SENSOR_IS_ON_CONDITION_SCHEMA = maybe_simple_id({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(BinarySensor),
 | 
			
		||||
    vol.Optional(CONF_FOR): cv.positive_time_period_milliseconds,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_BINARY_SENSOR_IS_ON, BINARY_SENSOR_IS_ON_CONDITION_SCHEMA)
 | 
			
		||||
def binary_sensor_is_on_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
def binary_sensor_is_on_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_binary_sensor_is_on_condition(template_arg)
 | 
			
		||||
    type = BinarySensorCondition.template(arg_type)
 | 
			
		||||
    rhs = var.make_binary_sensor_is_on_condition(template_arg, config.get(CONF_FOR))
 | 
			
		||||
    type = BinarySensorCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_BINARY_SENSOR_IS_OFF = 'binary_sensor.is_off'
 | 
			
		||||
BINARY_SENSOR_IS_OFF_CONDITION_SCHEMA = maybe_simple_id({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(BinarySensor),
 | 
			
		||||
    vol.Optional(CONF_FOR): cv.positive_time_period_milliseconds,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_BINARY_SENSOR_IS_OFF, BINARY_SENSOR_IS_OFF_CONDITION_SCHEMA)
 | 
			
		||||
def binary_sensor_is_off_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
def binary_sensor_is_off_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_binary_sensor_is_off_condition(template_arg)
 | 
			
		||||
    type = BinarySensorCondition.template(arg_type)
 | 
			
		||||
    rhs = var.make_binary_sensor_is_off_condition(template_arg, config.get(CONF_FOR))
 | 
			
		||||
    type = BinarySensorCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,3 @@ def to_code(config):
 | 
			
		||||
    func = getattr(hub, DIRECTIONS[config[CONF_DIRECTION]])
 | 
			
		||||
    rhs = func(config[CONF_NAME])
 | 
			
		||||
    binary_sensor.register_binary_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ import voluptuous as vol
 | 
			
		||||
from esphome.components import binary_sensor
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA, CONF_NAME
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, process_lambda, variable
 | 
			
		||||
from esphome.cpp_generator import add, process_lambda, variable
 | 
			
		||||
from esphome.cpp_types import std_vector
 | 
			
		||||
 | 
			
		||||
CustomBinarySensorConstructor = binary_sensor.binary_sensor_ns.class_(
 | 
			
		||||
@@ -27,13 +27,9 @@ def to_code(config):
 | 
			
		||||
    rhs = CustomBinarySensorConstructor(template_)
 | 
			
		||||
    custom = variable(config[CONF_ID], rhs)
 | 
			
		||||
    for i, conf in enumerate(config[CONF_BINARY_SENSORS]):
 | 
			
		||||
        var = Pvariable(conf[CONF_ID], custom.get_binary_sensor(i))
 | 
			
		||||
        add(var.set_name(conf[CONF_NAME]))
 | 
			
		||||
        binary_sensor.setup_binary_sensor(var, conf)
 | 
			
		||||
        rhs = custom.Pget_binary_sensor(i)
 | 
			
		||||
        add(rhs.set_name(conf[CONF_NAME]))
 | 
			
		||||
        binary_sensor.register_binary_sensor(rhs, conf)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_CUSTOM_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [binary_sensor.core_to_hass_config(data, sens) for sens in config[CONF_BINARY_SENSORS]]
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,3 @@ def to_code(config):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = hub.make_presence_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
 | 
			
		||||
    binary_sensor.register_binary_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_HOMEASSISTANT_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								esphome/components/binary_sensor/mpr121.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								esphome/components/binary_sensor/mpr121.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome.components import binary_sensor
 | 
			
		||||
from esphome.components.mpr121 import MPR121Component, CONF_MPR121_ID
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_CHANNEL, CONF_NAME
 | 
			
		||||
from esphome.cpp_generator import get_variable
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['mpr121']
 | 
			
		||||
MPR121Channel = binary_sensor.binary_sensor_ns.class_(
 | 
			
		||||
    'MPR121Channel', binary_sensor.BinarySensor)
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(MPR121Channel),
 | 
			
		||||
    cv.GenerateID(CONF_MPR121_ID): cv.use_variable_id(MPR121Component),
 | 
			
		||||
    vol.Required(CONF_CHANNEL): vol.All(vol.Coerce(int), vol.Range(min=0, max=11))
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for hub in get_variable(config[CONF_MPR121_ID]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = MPR121Channel.new(config[CONF_NAME], config[CONF_CHANNEL])
 | 
			
		||||
    binary_sensor.register_binary_sensor(hub.add_channel(rhs), config)
 | 
			
		||||
@@ -27,7 +27,3 @@ def to_code(config):
 | 
			
		||||
    rhs = hub.make_touch_component(config[CONF_NAME], config[CONF_PAGE_ID],
 | 
			
		||||
                                   config[CONF_COMPONENT_ID])
 | 
			
		||||
    binary_sensor.register_binary_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,3 @@ def to_code(config):
 | 
			
		||||
    addr = [HexInt(int(x, 16)) for x in config[CONF_UID].split('-')]
 | 
			
		||||
    rhs = hub.make_tag(config[CONF_NAME], addr)
 | 
			
		||||
    binary_sensor.register_binary_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,3 @@ def to_code(config):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = hub.make_card(config[CONF_NAME], config[CONF_UID])
 | 
			
		||||
    binary_sensor.register_binary_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', RCSwitchRawRec
 | 
			
		||||
 | 
			
		||||
def validate_raw(value):
 | 
			
		||||
    if isinstance(value, dict):
 | 
			
		||||
        return vol.Schema({
 | 
			
		||||
        return cv.Schema({
 | 
			
		||||
            cv.GenerateID(): cv.declare_variable_id(int32),
 | 
			
		||||
            vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
 | 
			
		||||
        })(value)
 | 
			
		||||
@@ -52,29 +52,29 @@ def validate_raw(value):
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(RemoteReceiver),
 | 
			
		||||
    vol.Optional(CONF_JVC): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_JVC): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_DATA): cv.hex_uint32_t,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_LG): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_LG): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_DATA): cv.hex_uint32_t,
 | 
			
		||||
        vol.Optional(CONF_NBITS, default=28): cv.one_of(28, 32, int=True),
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_NEC): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_NEC): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
 | 
			
		||||
        vol.Required(CONF_COMMAND): cv.hex_uint16_t,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_SAMSUNG): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_SAMSUNG): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_DATA): cv.hex_uint32_t,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_SONY): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_SONY): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_DATA): cv.hex_uint32_t,
 | 
			
		||||
        vol.Optional(CONF_NBITS, default=12): cv.one_of(12, 15, 20, int=True),
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_PANASONIC): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_PANASONIC): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
 | 
			
		||||
        vol.Required(CONF_COMMAND): cv.hex_uint32_t,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_RC5): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_RC5): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_ADDRESS): vol.All(cv.hex_int, vol.Range(min=0, max=0x1F)),
 | 
			
		||||
        vol.Required(CONF_COMMAND): vol.All(cv.hex_int, vol.Range(min=0, max=0x3F)),
 | 
			
		||||
    }),
 | 
			
		||||
@@ -145,7 +145,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_REMOTE_RECEIVER'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ def to_code(config):
 | 
			
		||||
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'
 | 
			
		||||
 | 
			
		||||
CONF_BINARY_SENSOR_TEMPLATE_PUBLISH = 'binary_sensor.template.publish'
 | 
			
		||||
BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(binary_sensor.BinarySensor),
 | 
			
		||||
    vol.Required(CONF_STATE): cv.templatable(cv.boolean),
 | 
			
		||||
})
 | 
			
		||||
@@ -44,17 +44,13 @@ BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_BINARY_SENSOR_TEMPLATE_PUBLISH,
 | 
			
		||||
                          BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA)
 | 
			
		||||
def binary_sensor_template_publish_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def binary_sensor_template_publish_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_binary_sensor_publish_action(template_arg)
 | 
			
		||||
    type = BinarySensorPublishAction.template(arg_type)
 | 
			
		||||
    type = BinarySensorPublishAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    for template_ in templatable(config[CONF_STATE], arg_type, bool_):
 | 
			
		||||
    for template_ in templatable(config[CONF_STATE], args, bool_):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.set_state(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return binary_sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -60,11 +60,11 @@ COVER_OPEN_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_COVER_OPEN, COVER_OPEN_ACTION_SCHEMA)
 | 
			
		||||
def cover_open_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def cover_open_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_open_action(template_arg)
 | 
			
		||||
    type = OpenAction.template(arg_type)
 | 
			
		||||
    type = OpenAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -75,11 +75,11 @@ COVER_CLOSE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_COVER_CLOSE, COVER_CLOSE_ACTION_SCHEMA)
 | 
			
		||||
def cover_close_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def cover_close_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_close_action(template_arg)
 | 
			
		||||
    type = CloseAction.template(arg_type)
 | 
			
		||||
    type = CloseAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -90,16 +90,9 @@ COVER_STOP_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_COVER_STOP, COVER_STOP_ACTION_SCHEMA)
 | 
			
		||||
def cover_stop_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def cover_stop_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_stop_action(template_arg)
 | 
			
		||||
    type = StopAction.template(arg_type)
 | 
			
		||||
    type = StopAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def core_to_hass_config(data, config):
 | 
			
		||||
    ret = mqtt.build_hass_config(data, 'cover', config, include_state=True, include_command=True)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ from esphome.const import CONF_ASSUMED_STATE, CONF_CLOSE_ACTION, CONF_ID, CONF_L
 | 
			
		||||
    CONF_OPEN_ACTION, CONF_OPTIMISTIC, CONF_STATE, CONF_STOP_ACTION
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
 | 
			
		||||
from esphome.cpp_helpers import setup_component
 | 
			
		||||
from esphome.cpp_types import Action, App, NoArg, optional
 | 
			
		||||
from esphome.cpp_types import Action, App, optional
 | 
			
		||||
from esphome.py_compat import string_types
 | 
			
		||||
 | 
			
		||||
TemplateCover = cover.cover_ns.class_('TemplateCover', cover.Cover)
 | 
			
		||||
@@ -38,14 +38,14 @@ def to_code(config):
 | 
			
		||||
            yield
 | 
			
		||||
        add(var.set_state_lambda(template_))
 | 
			
		||||
    if CONF_OPEN_ACTION in config:
 | 
			
		||||
        automation.build_automation(var.get_open_trigger(), NoArg,
 | 
			
		||||
                                    config[CONF_OPEN_ACTION])
 | 
			
		||||
        automation.build_automations(var.get_open_trigger(), [],
 | 
			
		||||
                                     config[CONF_OPEN_ACTION])
 | 
			
		||||
    if CONF_CLOSE_ACTION in config:
 | 
			
		||||
        automation.build_automation(var.get_close_trigger(), NoArg,
 | 
			
		||||
                                    config[CONF_CLOSE_ACTION])
 | 
			
		||||
        automation.build_automations(var.get_close_trigger(), [],
 | 
			
		||||
                                     config[CONF_CLOSE_ACTION])
 | 
			
		||||
    if CONF_STOP_ACTION in config:
 | 
			
		||||
        automation.build_automation(var.get_stop_trigger(), NoArg,
 | 
			
		||||
                                    config[CONF_STOP_ACTION])
 | 
			
		||||
        automation.build_automations(var.get_stop_trigger(), [],
 | 
			
		||||
                                     config[CONF_STOP_ACTION])
 | 
			
		||||
    if CONF_OPTIMISTIC in config:
 | 
			
		||||
        add(var.set_optimistic(config[CONF_OPTIMISTIC]))
 | 
			
		||||
    if CONF_ASSUMED_STATE in config:
 | 
			
		||||
@@ -55,7 +55,7 @@ def to_code(config):
 | 
			
		||||
BUILD_FLAGS = '-DUSE_TEMPLATE_COVER'
 | 
			
		||||
 | 
			
		||||
CONF_COVER_TEMPLATE_PUBLISH = 'cover.template.publish'
 | 
			
		||||
COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(cover.Cover),
 | 
			
		||||
    vol.Required(CONF_STATE): cv.templatable(cover.validate_cover_state),
 | 
			
		||||
})
 | 
			
		||||
@@ -63,26 +63,17 @@ COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_COVER_TEMPLATE_PUBLISH,
 | 
			
		||||
                          COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA)
 | 
			
		||||
def cover_template_publish_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def cover_template_publish_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_cover_publish_action(template_arg)
 | 
			
		||||
    type = CoverPublishAction.template(arg_type)
 | 
			
		||||
    type = CoverPublishAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    state = config[CONF_STATE]
 | 
			
		||||
    if isinstance(state, string_types):
 | 
			
		||||
        template_ = cover.COVER_STATES[state]
 | 
			
		||||
    else:
 | 
			
		||||
        for template_ in templatable(state, arg_type, cover.CoverState):
 | 
			
		||||
        for template_ in templatable(state, args, cover.CoverState):
 | 
			
		||||
            yield None
 | 
			
		||||
    add(action.set_state(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    ret = cover.core_to_hass_config(data, config)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    if CONF_OPTIMISTIC in config:
 | 
			
		||||
        ret['optimistic'] = config[CONF_OPTIMISTIC]
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,10 @@ from esphome.cpp_types import Component, ComponentPtr, esphome_ns, std_vector
 | 
			
		||||
CustomComponentConstructor = esphome_ns.class_('CustomComponentConstructor')
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(CustomComponentConstructor),
 | 
			
		||||
    vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Optional(CONF_COMPONENTS): cv.ensure_list(vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_COMPONENTS): cv.ensure_list(cv.Schema({
 | 
			
		||||
        cv.GenerateID(): cv.declare_variable_id(Component)
 | 
			
		||||
    }).extend(cv.COMPONENT_SCHEMA.schema)),
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,9 @@ from esphome.cpp_types import App, PollingComponent
 | 
			
		||||
DallasComponent = sensor.sensor_ns.class_('DallasComponent', PollingComponent)
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(DallasComponent),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.input_pullup_pin,
 | 
			
		||||
    vol.Required(CONF_PIN): pins.input_pin,
 | 
			
		||||
    vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,10 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.cpp_generator import add
 | 
			
		||||
from esphome.cpp_types import App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['logger']
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({})
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
 
 | 
			
		||||
@@ -38,14 +38,14 @@ EXT1_WAKEUP_MODES = {
 | 
			
		||||
CONF_WAKEUP_PIN_MODE = 'wakeup_pin_mode'
 | 
			
		||||
CONF_ESP32_EXT1_WAKEUP = 'esp32_ext1_wakeup'
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(DeepSleepComponent),
 | 
			
		||||
    vol.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_WAKEUP_PIN): vol.All(cv.only_on_esp32, pins.internal_gpio_input_pin_schema,
 | 
			
		||||
                                           validate_pin_number),
 | 
			
		||||
    vol.Optional(CONF_WAKEUP_PIN_MODE): vol.All(cv.only_on_esp32,
 | 
			
		||||
                                                cv.one_of(*WAKEUP_PIN_MODES), upper=True),
 | 
			
		||||
    vol.Optional(CONF_ESP32_EXT1_WAKEUP): vol.All(cv.only_on_esp32, vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ESP32_EXT1_WAKEUP): vol.All(cv.only_on_esp32, cv.Schema({
 | 
			
		||||
        vol.Required(CONF_PINS): cv.ensure_list(pins.shorthand_input_pin, validate_pin_number),
 | 
			
		||||
        vol.Required(CONF_MODE): cv.one_of(*EXT1_WAKEUP_MODES, upper=True),
 | 
			
		||||
    })),
 | 
			
		||||
@@ -95,11 +95,11 @@ DEEP_SLEEP_ENTER_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_DEEP_SLEEP_ENTER, DEEP_SLEEP_ENTER_ACTION_SCHEMA)
 | 
			
		||||
def deep_sleep_enter_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def deep_sleep_enter_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_enter_deep_sleep_action(template_arg)
 | 
			
		||||
    type = EnterDeepSleepAction.template(arg_type)
 | 
			
		||||
    type = EnterDeepSleepAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -110,9 +110,9 @@ DEEP_SLEEP_PREVENT_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_DEEP_SLEEP_PREVENT, DEEP_SLEEP_PREVENT_ACTION_SCHEMA)
 | 
			
		||||
def deep_sleep_prevent_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def deep_sleep_prevent_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_prevent_deep_sleep_action(template_arg)
 | 
			
		||||
    type = PreventDeepSleepAction.template(arg_type)
 | 
			
		||||
    type = PreventDeepSleepAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
@@ -78,11 +78,11 @@ DISPLAY_PAGE_SHOW_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_DISPLAY_PAGE_SHOW, DISPLAY_PAGE_SHOW_ACTION_SCHEMA)
 | 
			
		||||
def display_page_show_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    type = DisplayPageShowAction.template(arg_type)
 | 
			
		||||
def display_page_show_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    type = DisplayPageShowAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, type.new(), type=type)
 | 
			
		||||
    if isinstance(config[CONF_ID], core.Lambda):
 | 
			
		||||
        for template_ in templatable(config[CONF_ID], arg_type, DisplayPagePtr):
 | 
			
		||||
        for template_ in templatable(config[CONF_ID], args, DisplayPagePtr):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_page(template_))
 | 
			
		||||
    else:
 | 
			
		||||
@@ -99,10 +99,10 @@ DISPLAY_PAGE_SHOW_NEXT_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_DISPLAY_PAGE_SHOW_NEXT, DISPLAY_PAGE_SHOW_NEXT_ACTION_SCHEMA)
 | 
			
		||||
def display_page_show_next_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def display_page_show_next_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    type = DisplayPageShowNextAction.template(arg_type)
 | 
			
		||||
    type = DisplayPageShowNextAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, type.new(var), type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -113,10 +113,10 @@ DISPLAY_PAGE_SHOW_PREVIOUS_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_DISPLAY_PAGE_SHOW_PREVIOUS, DISPLAY_PAGE_SHOW_PREVIOUS_ACTION_SCHEMA)
 | 
			
		||||
def display_page_show_previous_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def display_page_show_previous_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    type = DisplayPageShowPrevAction.template(arg_type)
 | 
			
		||||
    type = DisplayPageShowPrevAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, type.new(var), type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,13 +7,14 @@ from esphome.cpp_helpers import setup_component
 | 
			
		||||
from esphome.cpp_types import App, Component, esphome_ns
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
CONFLICTS_WITH = ['esp32_ble_tracker']
 | 
			
		||||
 | 
			
		||||
ESP32BLEBeacon = esphome_ns.class_('ESP32BLEBeacon', Component)
 | 
			
		||||
 | 
			
		||||
CONF_MAJOR = 'major'
 | 
			
		||||
CONF_MINOR = 'minor'
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(ESP32BLEBeacon),
 | 
			
		||||
    vol.Required(CONF_TYPE): cv.one_of('IBEACON', upper=True),
 | 
			
		||||
    vol.Required(CONF_UUID): cv.uuid,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ XIAOMI_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(XiaomiSensor)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
 | 
			
		||||
    vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_seconds,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										130
									
								
								esphome/components/esp32_camera.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								esphome/components/esp32_camera.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome import config_validation as cv, pins
 | 
			
		||||
from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_NAME, CONF_PIN, CONF_SCL, CONF_SDA, \
 | 
			
		||||
    ESP_PLATFORM_ESP32
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add
 | 
			
		||||
from esphome.cpp_types import App, Nameable, PollingComponent, esphome_ns
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
 | 
			
		||||
ESP32Camera = esphome_ns.class_('ESP32Camera', PollingComponent, Nameable)
 | 
			
		||||
ESP32CameraFrameSize = esphome_ns.enum('ESP32CameraFrameSize')
 | 
			
		||||
FRAME_SIZES = {
 | 
			
		||||
    '160X120': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
 | 
			
		||||
    'QQVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
 | 
			
		||||
    '128x160': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_128X160,
 | 
			
		||||
    'QQVGA2': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_128X160,
 | 
			
		||||
    '176X144': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_176X144,
 | 
			
		||||
    'QCIF': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_176X144,
 | 
			
		||||
    '240X176': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_240X176,
 | 
			
		||||
    'HQVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_240X176,
 | 
			
		||||
    '320X240': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_320X240,
 | 
			
		||||
    'QVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_320X240,
 | 
			
		||||
    '400X296': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_400X296,
 | 
			
		||||
    'CIF': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_400X296,
 | 
			
		||||
    '640X480': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_640X480,
 | 
			
		||||
    'VGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_640X480,
 | 
			
		||||
    '800X600': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_800X600,
 | 
			
		||||
    'SVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_800X600,
 | 
			
		||||
    '1024X768': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1024X768,
 | 
			
		||||
    'XGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1024X768,
 | 
			
		||||
    '1280x1024': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1280X1024,
 | 
			
		||||
    'SXGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1280X1024,
 | 
			
		||||
    '1600X1200': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
 | 
			
		||||
    'UXGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CONF_DATA_PINS = 'data_pins'
 | 
			
		||||
CONF_VSYNC_PIN = 'vsync_pin'
 | 
			
		||||
CONF_HREF_PIN = 'href_pin'
 | 
			
		||||
CONF_PIXEL_CLOCK_PIN = 'pixel_clock_pin'
 | 
			
		||||
CONF_EXTERNAL_CLOCK = 'external_clock'
 | 
			
		||||
CONF_I2C_PINS = 'i2c_pins'
 | 
			
		||||
CONF_RESET_PIN = 'reset_pin'
 | 
			
		||||
CONF_POWER_DOWN_PIN = 'power_down_pin'
 | 
			
		||||
 | 
			
		||||
CONF_MAX_FRAMERATE = 'max_framerate'
 | 
			
		||||
CONF_IDLE_FRAMERATE = 'idle_framerate'
 | 
			
		||||
CONF_RESOLUTION = 'resolution'
 | 
			
		||||
CONF_JPEG_QUALITY = 'jpeg_quality'
 | 
			
		||||
CONF_VERTICAL_FLIP = 'vertical_flip'
 | 
			
		||||
CONF_HORIZONTAL_MIRROR = 'horizontal_mirror'
 | 
			
		||||
CONF_CONTRAST = 'contrast'
 | 
			
		||||
CONF_BRIGHTNESS = 'brightness'
 | 
			
		||||
CONF_SATURATION = 'saturation'
 | 
			
		||||
CONF_TEST_PATTERN = 'test_pattern'
 | 
			
		||||
 | 
			
		||||
camera_range_param = vol.All(cv.int_, vol.Range(min=-2, max=2))
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(ESP32Camera),
 | 
			
		||||
    vol.Required(CONF_NAME): cv.string,
 | 
			
		||||
    vol.Required(CONF_DATA_PINS): vol.All([pins.input_pin], vol.Length(min=8, max=8)),
 | 
			
		||||
    vol.Required(CONF_VSYNC_PIN): pins.input_pin,
 | 
			
		||||
    vol.Required(CONF_HREF_PIN): pins.input_pin,
 | 
			
		||||
    vol.Required(CONF_PIXEL_CLOCK_PIN): pins.input_pin,
 | 
			
		||||
    vol.Required(CONF_EXTERNAL_CLOCK): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_PIN): pins.output_pin,
 | 
			
		||||
        vol.Optional(CONF_FREQUENCY, default='20MHz'): vol.All(cv.frequency, vol.In([20e6, 10e6])),
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Required(CONF_I2C_PINS): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_SDA): pins.output_pin,
 | 
			
		||||
        vol.Required(CONF_SCL): pins.output_pin,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_RESET_PIN): pins.output_pin,
 | 
			
		||||
    vol.Optional(CONF_POWER_DOWN_PIN): pins.output_pin,
 | 
			
		||||
 | 
			
		||||
    vol.Optional(CONF_MAX_FRAMERATE, default='10 fps'): vol.All(cv.framerate,
 | 
			
		||||
                                                                vol.Range(min=0, min_included=False,
 | 
			
		||||
                                                                          max=60)),
 | 
			
		||||
    vol.Optional(CONF_IDLE_FRAMERATE, default='0.1 fps'): vol.All(cv.framerate,
 | 
			
		||||
                                                                  vol.Range(min=0, max=1)),
 | 
			
		||||
    vol.Optional(CONF_RESOLUTION, default='640X480'): cv.one_of(*FRAME_SIZES, upper=True),
 | 
			
		||||
    vol.Optional(CONF_JPEG_QUALITY, default=10): vol.All(cv.int_, vol.Range(min=10, max=63)),
 | 
			
		||||
    vol.Optional(CONF_CONTRAST, default=0): camera_range_param,
 | 
			
		||||
    vol.Optional(CONF_BRIGHTNESS, default=0): camera_range_param,
 | 
			
		||||
    vol.Optional(CONF_SATURATION, default=0): camera_range_param,
 | 
			
		||||
    vol.Optional(CONF_VERTICAL_FLIP, default=True): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_HORIZONTAL_MIRROR, default=True): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_TEST_PATTERN, default=False): cv.boolean,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
SETTERS = {
 | 
			
		||||
    CONF_DATA_PINS: 'set_data_pins',
 | 
			
		||||
    CONF_VSYNC_PIN: 'set_vsync_pin',
 | 
			
		||||
    CONF_HREF_PIN: 'set_href_pin',
 | 
			
		||||
    CONF_PIXEL_CLOCK_PIN: 'set_pixel_clock_pin',
 | 
			
		||||
    CONF_RESET_PIN: 'set_reset_pin',
 | 
			
		||||
    CONF_POWER_DOWN_PIN: 'set_power_down_pin',
 | 
			
		||||
    CONF_JPEG_QUALITY: 'set_jpeg_quality',
 | 
			
		||||
    CONF_VERTICAL_FLIP: 'set_vertical_flip',
 | 
			
		||||
    CONF_HORIZONTAL_MIRROR: 'set_horizontal_mirror',
 | 
			
		||||
    CONF_CONTRAST: 'set_contrast',
 | 
			
		||||
    CONF_BRIGHTNESS: 'set_brightness',
 | 
			
		||||
    CONF_SATURATION: 'set_saturation',
 | 
			
		||||
    CONF_TEST_PATTERN: 'set_test_pattern',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    rhs = App.register_component(ESP32Camera.new(config[CONF_NAME]))
 | 
			
		||||
    cam = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 | 
			
		||||
    for key, setter in SETTERS.items():
 | 
			
		||||
        if key in config:
 | 
			
		||||
            add(getattr(cam, setter)(config[key]))
 | 
			
		||||
 | 
			
		||||
    extclk = config[CONF_EXTERNAL_CLOCK]
 | 
			
		||||
    add(cam.set_external_clock(extclk[CONF_PIN], extclk[CONF_FREQUENCY]))
 | 
			
		||||
    i2c_pins = config[CONF_I2C_PINS]
 | 
			
		||||
    add(cam.set_i2c_pins(i2c_pins[CONF_SDA], i2c_pins[CONF_SCL]))
 | 
			
		||||
    add(cam.set_max_update_interval(1000 / config[CONF_MAX_FRAMERATE]))
 | 
			
		||||
    if config[CONF_IDLE_FRAMERATE] == 0:
 | 
			
		||||
        add(cam.set_idle_update_interval(0))
 | 
			
		||||
    else:
 | 
			
		||||
        add(cam.set_idle_update_interval(1000 / config[CONF_IDLE_FRAMERATE]))
 | 
			
		||||
    add(cam.set_frame_size(FRAME_SIZES[config[CONF_RESOLUTION]]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = ['-DUSE_ESP32_CAMERA', '-DBOARD_HAS_PSRAM']
 | 
			
		||||
@@ -46,7 +46,7 @@ VOLTAGE_ATTENUATION = {
 | 
			
		||||
 | 
			
		||||
ESP32TouchComponent = binary_sensor.binary_sensor_ns.class_('ESP32TouchComponent', Component)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(ESP32TouchComponent),
 | 
			
		||||
    vol.Optional(CONF_SETUP_MODE): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_IIR_FILTER): cv.positive_time_period_milliseconds,
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,7 @@ def validate(config):
 | 
			
		||||
    return config
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(EthernetComponent),
 | 
			
		||||
    vol.Required(CONF_TYPE): cv.one_of(*ETHERNET_TYPES, upper=True),
 | 
			
		||||
    vol.Required(CONF_MDC_PIN): pins.output_pin,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,9 @@ from esphome.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
from esphome.components import mqtt
 | 
			
		||||
from esphome.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID, CONF_NAME, CONF_OSCILLATING, \
 | 
			
		||||
    CONF_OSCILLATION_COMMAND_TOPIC, CONF_OSCILLATION_OUTPUT, CONF_OSCILLATION_STATE_TOPIC, \
 | 
			
		||||
    CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC
 | 
			
		||||
from esphome.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID, CONF_OSCILLATING, \
 | 
			
		||||
    CONF_OSCILLATION_COMMAND_TOPIC, CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED, \
 | 
			
		||||
    CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, get_variable, templatable
 | 
			
		||||
from esphome.cpp_types import Action, Application, Component, Nameable, bool_, esphome_ns
 | 
			
		||||
@@ -81,11 +81,11 @@ FAN_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_FAN_TOGGLE, FAN_TOGGLE_ACTION_SCHEMA)
 | 
			
		||||
def fan_toggle_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def fan_toggle_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_toggle_action(template_arg)
 | 
			
		||||
    type = ToggleAction.template(arg_type)
 | 
			
		||||
    type = ToggleAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -96,11 +96,11 @@ FAN_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_FAN_TURN_OFF, FAN_TURN_OFF_ACTION_SCHEMA)
 | 
			
		||||
def fan_turn_off_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def fan_turn_off_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_off_action(template_arg)
 | 
			
		||||
    type = TurnOffAction.template(arg_type)
 | 
			
		||||
    type = TurnOffAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -113,32 +113,20 @@ FAN_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_FAN_TURN_ON, FAN_TURN_ON_ACTION_SCHEMA)
 | 
			
		||||
def fan_turn_on_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def fan_turn_on_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_on_action(template_arg)
 | 
			
		||||
    type = TurnOnAction.template(arg_type)
 | 
			
		||||
    type = TurnOnAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    if CONF_OSCILLATING in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_OSCILLATING], arg_type, bool_):
 | 
			
		||||
        for template_ in templatable(config[CONF_OSCILLATING], args, bool_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_oscillating(template_))
 | 
			
		||||
    if CONF_SPEED in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_SPEED], arg_type, FanSpeed):
 | 
			
		||||
        for template_ in templatable(config[CONF_SPEED], args, FanSpeed):
 | 
			
		||||
            yield None
 | 
			
		||||
        if isinstance(template_, string_types):
 | 
			
		||||
            template_ = FAN_SPEEDS[template_]
 | 
			
		||||
        add(action.set_speed(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def core_to_hass_config(data, config):
 | 
			
		||||
    ret = mqtt.build_hass_config(data, 'fan', config, include_state=True, include_command=True)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    if CONF_OSCILLATION_OUTPUT in config:
 | 
			
		||||
        default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'oscillation/state')
 | 
			
		||||
        ret['oscillation_state_topic'] = config.get(CONF_OSCILLATION_STATE_TOPIC, default)
 | 
			
		||||
        default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'oscillation/command')
 | 
			
		||||
        ret['oscillation_command__topic'] = config.get(CONF_OSCILLATION_COMMAND_TOPIC, default)
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
    fan.setup_fan(fan_struct.Pstate, config)
 | 
			
		||||
    setup_component(fan_struct.Poutput, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return fan.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome.components import fan, mqtt, output
 | 
			
		||||
from esphome.components import fan, output
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_HIGH, CONF_LOW, CONF_MAKE_ID, CONF_MEDIUM, CONF_NAME, \
 | 
			
		||||
    CONF_OSCILLATION_OUTPUT, CONF_OUTPUT, CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, \
 | 
			
		||||
@@ -14,7 +14,7 @@ PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic,
 | 
			
		||||
    vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic,
 | 
			
		||||
    vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(output.BinaryOutput),
 | 
			
		||||
    vol.Optional(CONF_SPEED): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_SPEED): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_LOW): cv.percentage,
 | 
			
		||||
        vol.Required(CONF_MEDIUM): cv.percentage,
 | 
			
		||||
        vol.Required(CONF_HIGH): cv.percentage,
 | 
			
		||||
@@ -42,14 +42,3 @@ def to_code(config):
 | 
			
		||||
        add(fan_struct.Poutput.set_oscillation(oscillation_output))
 | 
			
		||||
 | 
			
		||||
    fan.setup_fan(fan_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    ret = fan.core_to_hass_config(data, config)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'speed/state')
 | 
			
		||||
    ret['speed_state_topic'] = config.get(CONF_SPEED_STATE_TOPIC, default)
 | 
			
		||||
    default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'speed/command')
 | 
			
		||||
    ret['speed_command__topic'] = config.get(CONF_SPEED_COMMAND_TOPIC, default)
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,8 @@ Glyph = display.display_ns.class_('Glyph')
 | 
			
		||||
 | 
			
		||||
def validate_glyphs(value):
 | 
			
		||||
    if isinstance(value, list):
 | 
			
		||||
        value = vol.Schema([cv.string])(value)
 | 
			
		||||
    value = vol.Schema([cv.string])(list(value))
 | 
			
		||||
        value = cv.Schema([cv.string])(value)
 | 
			
		||||
    value = cv.Schema([cv.string])(list(value))
 | 
			
		||||
 | 
			
		||||
    def comparator(x, y):
 | 
			
		||||
        x_ = x.encode('utf-8')
 | 
			
		||||
@@ -69,7 +69,7 @@ def validate_truetype_file(value):
 | 
			
		||||
DEFAULT_GLYPHS = u' !"%()+,-.:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°'
 | 
			
		||||
CONF_RAW_DATA_ID = 'raw_data_id'
 | 
			
		||||
 | 
			
		||||
FONT_SCHEMA = vol.Schema({
 | 
			
		||||
FONT_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(Font),
 | 
			
		||||
    vol.Required(CONF_FILE): validate_truetype_file,
 | 
			
		||||
    vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ GlobalVariableComponent = esphome_ns.class_('GlobalVariableComponent', Component
 | 
			
		||||
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(GlobalVariableComponent),
 | 
			
		||||
    vol.Required(CONF_TYPE): cv.string_strict,
 | 
			
		||||
    vol.Optional(CONF_INITIAL_VALUE): cv.string_strict,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,12 +11,12 @@ from esphome.cpp_types import App, Component, esphome_ns
 | 
			
		||||
I2CComponent = esphome_ns.class_('I2CComponent', Component)
 | 
			
		||||
I2CDevice = pins.I2CDevice
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(I2CComponent),
 | 
			
		||||
    vol.Optional(CONF_SDA, default='SDA'): pins.input_pullup_pin,
 | 
			
		||||
    vol.Optional(CONF_SCL, default='SCL'): pins.input_pullup_pin,
 | 
			
		||||
    vol.Optional(CONF_SDA, default='SDA'): pins.input_pin,
 | 
			
		||||
    vol.Optional(CONF_SCL, default='SCL'): pins.input_pin,
 | 
			
		||||
    vol.Optional(CONF_FREQUENCY): vol.All(cv.frequency, vol.Range(min=0, min_included=False)),
 | 
			
		||||
    vol.Optional(CONF_SCAN): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_SCAN, default=True): cv.boolean,
 | 
			
		||||
 | 
			
		||||
    vol.Optional(CONF_RECEIVE_TIMEOUT): cv.invalid("The receive_timeout option has been removed "
 | 
			
		||||
                                                   "because timeouts are already handled by the "
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ Image_ = display.display_ns.class_('Image')
 | 
			
		||||
 | 
			
		||||
CONF_RAW_DATA_ID = 'raw_data_id'
 | 
			
		||||
 | 
			
		||||
IMAGE_SCHEMA = vol.Schema({
 | 
			
		||||
IMAGE_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(Image_),
 | 
			
		||||
    vol.Required(CONF_FILE): cv.file_,
 | 
			
		||||
    vol.Optional(CONF_RESIZE): cv.dimensions,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,11 @@ import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID, CONF_INTERVAL
 | 
			
		||||
from esphome.cpp_generator import Pvariable
 | 
			
		||||
from esphome.cpp_helpers import setup_component
 | 
			
		||||
from esphome.cpp_types import App, NoArg, PollingComponent, Trigger, esphome_ns
 | 
			
		||||
from esphome.cpp_types import App, PollingComponent, Trigger, esphome_ns
 | 
			
		||||
 | 
			
		||||
IntervalTrigger = esphome_ns.class_('IntervalTrigger', Trigger.template(NoArg), PollingComponent)
 | 
			
		||||
IntervalTrigger = esphome_ns.class_('IntervalTrigger', Trigger.template(), PollingComponent)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = automation.validate_automation(vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = automation.validate_automation(cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(IntervalTrigger),
 | 
			
		||||
    vol.Required(CONF_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema))
 | 
			
		||||
@@ -21,4 +21,4 @@ def to_code(config):
 | 
			
		||||
        trigger = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        setup_component(trigger, conf)
 | 
			
		||||
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 
 | 
			
		||||
@@ -88,22 +88,22 @@ ADDRESSABLE_EFFECTS = RGB_EFFECTS + [CONF_ADDRESSABLE_LAMBDA, CONF_ADDRESSABLE_R
 | 
			
		||||
                                     CONF_ADDRESSABLE_TWINKLE, CONF_ADDRESSABLE_RANDOM_TWINKLE,
 | 
			
		||||
                                     CONF_ADDRESSABLE_FIREWORKS, CONF_ADDRESSABLE_FLICKER]
 | 
			
		||||
 | 
			
		||||
EFFECTS_SCHEMA = vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_LAMBDA): vol.Schema({
 | 
			
		||||
EFFECTS_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Optional(CONF_LAMBDA): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_NAME): cv.string,
 | 
			
		||||
        vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
        vol.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_RANDOM): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_RANDOM): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(RandomLightEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Random"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
 | 
			
		||||
        vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_STROBE): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_STROBE): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(StrobeLightEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Strobe"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_COLORS): vol.All(cv.ensure_list(vol.Schema({
 | 
			
		||||
        vol.Optional(CONF_COLORS): vol.All(cv.ensure_list(cv.Schema({
 | 
			
		||||
            vol.Optional(CONF_STATE, default=True): cv.boolean,
 | 
			
		||||
            vol.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
 | 
			
		||||
            vol.Optional(CONF_RED, default=1.0): cv.percentage,
 | 
			
		||||
@@ -114,24 +114,24 @@ EFFECTS_SCHEMA = vol.Schema({
 | 
			
		||||
        }), cv.has_at_least_one_key(CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE,
 | 
			
		||||
                                    CONF_WHITE)), vol.Length(min=2)),
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_FLICKER): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_FLICKER): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(FlickerLightEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Flicker"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_ALPHA): cv.percentage,
 | 
			
		||||
        vol.Optional(CONF_INTENSITY): cv.percentage,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_LAMBDA): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_LAMBDA): cv.Schema({
 | 
			
		||||
        vol.Required(CONF_NAME): cv.string,
 | 
			
		||||
        vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
        vol.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_RAINBOW): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_RAINBOW): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableRainbowLightEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Rainbow"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_SPEED): cv.uint32_t,
 | 
			
		||||
        vol.Optional(CONF_WIDTH): cv.uint32_t,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_COLOR_WIPE): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_COLOR_WIPE): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableColorWipeEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Color Wipe"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_COLORS): cv.ensure_list({
 | 
			
		||||
@@ -145,24 +145,24 @@ EFFECTS_SCHEMA = vol.Schema({
 | 
			
		||||
        vol.Optional(CONF_ADD_LED_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
        vol.Optional(CONF_REVERSE): cv.boolean,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_SCAN): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_SCAN): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableScanEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Scan"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_MOVE_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_TWINKLE): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_TWINKLE): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableTwinkleEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Twinkle"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage,
 | 
			
		||||
        vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_RANDOM_TWINKLE): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_RANDOM_TWINKLE): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableRandomTwinkleEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Random Twinkle"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_TWINKLE_PROBABILITY): cv.percentage,
 | 
			
		||||
        vol.Optional(CONF_PROGRESS_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_FIREWORKS): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_FIREWORKS): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableFireworksEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Fireworks"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
@@ -170,7 +170,7 @@ EFFECTS_SCHEMA = vol.Schema({
 | 
			
		||||
        vol.Optional(CONF_USE_RANDOM_COLOR): cv.boolean,
 | 
			
		||||
        vol.Optional(CONF_FADE_OUT_RATE): cv.uint8_t,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_FLICKER): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ADDRESSABLE_FLICKER): cv.Schema({
 | 
			
		||||
        cv.GenerateID(CONF_EFFECT_ID): cv.declare_variable_id(AddressableFlickerEffect),
 | 
			
		||||
        vol.Optional(CONF_NAME, default="Addressable Flicker"): cv.string,
 | 
			
		||||
        vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds,
 | 
			
		||||
@@ -404,14 +404,14 @@ LIGHT_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_LIGHT_TOGGLE, LIGHT_TOGGLE_ACTION_SCHEMA)
 | 
			
		||||
def light_toggle_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def light_toggle_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_toggle_action(template_arg)
 | 
			
		||||
    type = ToggleAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    if CONF_TRANSITION_LENGTH in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
 | 
			
		||||
        for template_ in templatable(config[CONF_TRANSITION_LENGTH], args, uint32):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_transition_length(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
@@ -425,14 +425,14 @@ LIGHT_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_LIGHT_TURN_OFF, LIGHT_TURN_OFF_ACTION_SCHEMA)
 | 
			
		||||
def light_turn_off_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def light_turn_off_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_off_action(template_arg)
 | 
			
		||||
    type = TurnOffAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    if CONF_TRANSITION_LENGTH in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
 | 
			
		||||
        for template_ in templatable(config[CONF_TRANSITION_LENGTH], args, uint32):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_transition_length(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
@@ -456,67 +456,46 @@ LIGHT_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_LIGHT_TURN_ON, LIGHT_TURN_ON_ACTION_SCHEMA)
 | 
			
		||||
def light_turn_on_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def light_turn_on_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_on_action(template_arg)
 | 
			
		||||
    type = TurnOnAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    if CONF_TRANSITION_LENGTH in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
 | 
			
		||||
        for template_ in templatable(config[CONF_TRANSITION_LENGTH], args, uint32):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_transition_length(template_))
 | 
			
		||||
    if CONF_FLASH_LENGTH in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_FLASH_LENGTH], arg_type, uint32):
 | 
			
		||||
        for template_ in templatable(config[CONF_FLASH_LENGTH], args, uint32):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_flash_length(template_))
 | 
			
		||||
    if CONF_BRIGHTNESS in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_BRIGHTNESS], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_BRIGHTNESS], args, float_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_brightness(template_))
 | 
			
		||||
    if CONF_RED in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_RED], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_RED], args, float_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_red(template_))
 | 
			
		||||
    if CONF_GREEN in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_GREEN], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_GREEN], args, float_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_green(template_))
 | 
			
		||||
    if CONF_BLUE in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_BLUE], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_BLUE], args, float_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_blue(template_))
 | 
			
		||||
    if CONF_WHITE in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_WHITE], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_WHITE], args, float_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_white(template_))
 | 
			
		||||
    if CONF_COLOR_TEMPERATURE in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_COLOR_TEMPERATURE], arg_type, float_):
 | 
			
		||||
        for template_ in templatable(config[CONF_COLOR_TEMPERATURE], args, float_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_color_temperature(template_))
 | 
			
		||||
    if CONF_EFFECT in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_EFFECT], arg_type, std_string):
 | 
			
		||||
        for template_ in templatable(config[CONF_EFFECT], args, std_string):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_effect(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=True,
 | 
			
		||||
                        white_value=True):
 | 
			
		||||
    ret = mqtt.build_hass_config(data, 'light', config, include_state=True, include_command=True)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    ret['schema'] = 'json'
 | 
			
		||||
    if brightness:
 | 
			
		||||
        ret['brightness'] = True
 | 
			
		||||
    if rgb:
 | 
			
		||||
        ret['rgb'] = True
 | 
			
		||||
    if color_temp:
 | 
			
		||||
        ret['color_temp'] = True
 | 
			
		||||
    if white_value:
 | 
			
		||||
        ret['white_value'] = True
 | 
			
		||||
    for effect in config.get(CONF_EFFECTS, []):
 | 
			
		||||
        ret["effect"] = True
 | 
			
		||||
        effects = ret.setdefault("effect_list", [])
 | 
			
		||||
        effects.append(next(x for x in effect.values())[CONF_NAME])
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,3 @@ def to_code(config):
 | 
			
		||||
    light_struct = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(light_struct.Pstate, config)
 | 
			
		||||
    setup_component(light_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=False, rgb=False, color_temp=False,
 | 
			
		||||
                                     white_value=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,3 @@ def to_code(config):
 | 
			
		||||
    light_struct = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(light_struct.Pstate, config)
 | 
			
		||||
    setup_component(light_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=False, color_temp=True,
 | 
			
		||||
                                     white_value=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -106,8 +106,3 @@ def to_code(config):
 | 
			
		||||
REQUIRED_BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'
 | 
			
		||||
 | 
			
		||||
LIB_DEPS = 'FastLED@3.2.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
 | 
			
		||||
                                     white_value=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -86,8 +86,3 @@ def to_code(config):
 | 
			
		||||
REQUIRED_BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'
 | 
			
		||||
 | 
			
		||||
LIB_DEPS = 'FastLED@3.2.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
 | 
			
		||||
                                     white_value=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,8 +24,3 @@ def to_code(config):
 | 
			
		||||
    light_struct = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(light_struct.Pstate, config)
 | 
			
		||||
    setup_component(light_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=False, color_temp=False,
 | 
			
		||||
                                     white_value=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -188,8 +188,3 @@ def to_code(config):
 | 
			
		||||
REQUIRED_BUILD_FLAGS = '-DUSE_NEO_PIXEL_BUS_LIGHT'
 | 
			
		||||
 | 
			
		||||
LIB_DEPS = 'NeoPixelBus@2.4.1'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
 | 
			
		||||
                                     white_value='W' in config[CONF_TYPE])
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,3 @@ def to_code(config):
 | 
			
		||||
    rhs = App.make_partition_light(config[CONF_NAME], segments)
 | 
			
		||||
    make = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(make.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,3 @@ def to_code(config):
 | 
			
		||||
    light_struct = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(light_struct.Pstate, config)
 | 
			
		||||
    setup_component(light_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
 | 
			
		||||
                                     white_value=False)
 | 
			
		||||
 
 | 
			
		||||
@@ -33,8 +33,3 @@ def to_code(config):
 | 
			
		||||
    light_struct = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(light_struct.Pstate, config)
 | 
			
		||||
    setup_component(light_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
 | 
			
		||||
                                     white_value=True)
 | 
			
		||||
 
 | 
			
		||||
@@ -63,8 +63,3 @@ def to_code(config):
 | 
			
		||||
    light_struct = variable(config[CONF_MAKE_ID], rhs)
 | 
			
		||||
    light.setup_light(light_struct.Pstate, config)
 | 
			
		||||
    setup_component(light_struct.Pstate, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=True,
 | 
			
		||||
                                     white_value=True)
 | 
			
		||||
 
 | 
			
		||||
@@ -73,13 +73,13 @@ def validate_local_no_higher_than_global(value):
 | 
			
		||||
 | 
			
		||||
LogComponent = esphome_ns.class_('LogComponent', Component)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(LogComponent),
 | 
			
		||||
    vol.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
 | 
			
		||||
    vol.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes,
 | 
			
		||||
    vol.Optional(CONF_HARDWARE_UART, default='UART0'): uart_selection,
 | 
			
		||||
    vol.Optional(CONF_LEVEL): is_log_level,
 | 
			
		||||
    vol.Optional(CONF_LOGS): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_LOGS): cv.Schema({
 | 
			
		||||
        cv.string: is_log_level,
 | 
			
		||||
    })
 | 
			
		||||
}), validate_local_no_higher_than_global)
 | 
			
		||||
@@ -102,7 +102,9 @@ def required_build_flags(config):
 | 
			
		||||
        flags.append(u'-DESPHOME_LOG_LEVEL={}'.format(str(LOG_LEVELS[config[CONF_LEVEL]])))
 | 
			
		||||
        this_severity = LOG_LEVEL_SEVERITY.index(config[CONF_LEVEL])
 | 
			
		||||
        verbose_severity = LOG_LEVEL_SEVERITY.index('VERBOSE')
 | 
			
		||||
        very_verbose_severity = LOG_LEVEL_SEVERITY.index('VERY_VERBOSE')
 | 
			
		||||
        is_at_least_verbose = this_severity >= verbose_severity
 | 
			
		||||
        is_at_least_very_verbose = this_severity >= very_verbose_severity
 | 
			
		||||
        has_serial_logging = config.get(CONF_BAUD_RATE) != 0
 | 
			
		||||
        if CORE.is_esp8266 and has_serial_logging and is_at_least_verbose:
 | 
			
		||||
            debug_serial_port = HARDWARE_UART_TO_SERIAL[config.get(CONF_HARDWARE_UART)]
 | 
			
		||||
@@ -122,6 +124,8 @@ def required_build_flags(config):
 | 
			
		||||
                flags.append(u"-DDEBUG_ESP_{}".format(comp))
 | 
			
		||||
        if CORE.is_esp32 and is_at_least_verbose:
 | 
			
		||||
            flags.append('-DCORE_DEBUG_LEVEL=5')
 | 
			
		||||
        if CORE.is_esp32 and is_at_least_very_verbose:
 | 
			
		||||
            flags.append('-DENABLE_I2C_DEBUG_BUFFER')
 | 
			
		||||
 | 
			
		||||
    return flags
 | 
			
		||||
 | 
			
		||||
@@ -129,8 +133,8 @@ def required_build_flags(config):
 | 
			
		||||
def maybe_simple_message(schema):
 | 
			
		||||
    def validator(value):
 | 
			
		||||
        if isinstance(value, dict):
 | 
			
		||||
            return vol.Schema(schema)(value)
 | 
			
		||||
        return vol.Schema(schema)({CONF_FORMAT: value})
 | 
			
		||||
            return cv.Schema(schema)(value)
 | 
			
		||||
        return cv.Schema(schema)({CONF_FORMAT: value})
 | 
			
		||||
 | 
			
		||||
    return validator
 | 
			
		||||
 | 
			
		||||
@@ -167,13 +171,13 @@ LOGGER_LOG_ACTION_SCHEMA = vol.All(maybe_simple_message({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_LOGGER_LOG, LOGGER_LOG_ACTION_SCHEMA)
 | 
			
		||||
def logger_log_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def logger_log_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    esp_log = LOG_LEVEL_TO_ESP_LOG[config[CONF_LEVEL]]
 | 
			
		||||
    args = [RawExpression(text_type(x)) for x in config[CONF_ARGS]]
 | 
			
		||||
    args_ = [RawExpression(text_type(x)) for x in config[CONF_ARGS]]
 | 
			
		||||
 | 
			
		||||
    text = text_type(statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args)))
 | 
			
		||||
    text = text_type(statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args_)))
 | 
			
		||||
 | 
			
		||||
    for lambda_ in process_lambda(Lambda(text), [(arg_type, 'x')], return_type=void):
 | 
			
		||||
    for lambda_ in process_lambda(Lambda(text), args, return_type=void):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = LambdaAction.new(template_arg, lambda_)
 | 
			
		||||
    type = LambdaAction.template(template_arg)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								esphome/components/mcp23017.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								esphome/components/mcp23017.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome import pins
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ADDRESS, CONF_ID
 | 
			
		||||
from esphome.cpp_generator import Pvariable
 | 
			
		||||
from esphome.cpp_helpers import setup_component
 | 
			
		||||
from esphome.cpp_types import App, GPIOInputPin, GPIOOutputPin, io_ns, esphome_ns
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
MCP23017GPIOMode = esphome_ns.enum('MCP23017GPIOMode')
 | 
			
		||||
MCP23017_GPIO_MODES = {
 | 
			
		||||
    'INPUT': MCP23017GPIOMode.MCP23017_INPUT,
 | 
			
		||||
    'INPUT_PULLUP': MCP23017GPIOMode.MCP23017_INPUT_PULLUP,
 | 
			
		||||
    'OUTPUT': MCP23017GPIOMode.MCP23017_OUTPUT,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MCP23017GPIOInputPin = io_ns.class_('MCP23017GPIOInputPin', GPIOInputPin)
 | 
			
		||||
MCP23017GPIOOutputPin = io_ns.class_('MCP23017GPIOOutputPin', GPIOOutputPin)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(pins.MCP23017),
 | 
			
		||||
    vol.Optional(CONF_ADDRESS, default=0x20): cv.i2c_address,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    rhs = App.make_mcp23017_component(config[CONF_ADDRESS])
 | 
			
		||||
    var = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    setup_component(var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_MCP23017'
 | 
			
		||||
							
								
								
									
										29
									
								
								esphome/components/mpr121.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								esphome/components/mpr121.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome.components import i2c, binary_sensor
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ADDRESS, CONF_ID
 | 
			
		||||
from esphome.cpp_generator import Pvariable
 | 
			
		||||
from esphome.cpp_helpers import setup_component
 | 
			
		||||
from esphome.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONF_MPR121_ID = 'mpr121_id'
 | 
			
		||||
MPR121Component = binary_sensor.binary_sensor_ns.class_('MPR121Component', Component, i2c.I2CDevice)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(MPR121Component),
 | 
			
		||||
    vol.Optional(CONF_ADDRESS): cv.i2c_address
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    rhs = App.make_mpr121(config.get(CONF_ADDRESS))
 | 
			
		||||
    var = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 | 
			
		||||
    setup_component(var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_MPR121'
 | 
			
		||||
@@ -1,20 +1,18 @@
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome import automation
 | 
			
		||||
from esphome.automation import ACTION_REGISTRY
 | 
			
		||||
from esphome.automation import ACTION_REGISTRY, CONDITION_REGISTRY, Condition
 | 
			
		||||
from esphome.components import logger
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_AVAILABILITY, CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, \
 | 
			
		||||
    CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, \
 | 
			
		||||
    CONF_ESPHOME, CONF_ID, CONF_INTERNAL, CONF_KEEPALIVE, CONF_LEVEL, CONF_LOG_TOPIC, \
 | 
			
		||||
    CONF_MQTT, CONF_NAME, CONF_ON_JSON_MESSAGE, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, \
 | 
			
		||||
    CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PORT, CONF_QOS, CONF_REBOOT_TIMEOUT, \
 | 
			
		||||
    CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_STATE_TOPIC, CONF_TOPIC, \
 | 
			
		||||
    CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE
 | 
			
		||||
from esphome.core import EsphomeError
 | 
			
		||||
    CONF_ID, CONF_KEEPALIVE, CONF_LEVEL, CONF_LOG_TOPIC, CONF_ON_JSON_MESSAGE, CONF_ON_MESSAGE, \
 | 
			
		||||
    CONF_PASSWORD, CONF_PAYLOAD, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PORT, \
 | 
			
		||||
    CONF_QOS, CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, \
 | 
			
		||||
    CONF_STATE_TOPIC, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \
 | 
			
		||||
    CONF_WILL_MESSAGE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, RawExpression, StructInitializer, TemplateArguments, \
 | 
			
		||||
    add, get_variable, process_lambda, templatable
 | 
			
		||||
from esphome.cpp_types import Action, App, Component, JsonObjectConstRef, JsonObjectRef, \
 | 
			
		||||
@@ -26,7 +24,7 @@ def validate_message_just_topic(value):
 | 
			
		||||
    return MQTT_MESSAGE_BASE({CONF_TOPIC: value})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MQTT_MESSAGE_BASE = vol.Schema({
 | 
			
		||||
MQTT_MESSAGE_BASE = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_TOPIC): cv.publish_topic,
 | 
			
		||||
    vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
 | 
			
		||||
    vol.Optional(CONF_RETAIN, default=True): cv.boolean,
 | 
			
		||||
@@ -47,6 +45,7 @@ MQTTMessageTrigger = mqtt_ns.class_('MQTTMessageTrigger', Trigger.template(std_s
 | 
			
		||||
MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger',
 | 
			
		||||
                                        Trigger.template(JsonObjectConstRef))
 | 
			
		||||
MQTTComponent = mqtt_ns.class_('MQTTComponent', Component)
 | 
			
		||||
MQTTConnectedCondition = mqtt_ns.class_('MQTTConnectedCondition', Condition)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_config(value):
 | 
			
		||||
@@ -67,7 +66,7 @@ def validate_fingerprint(value):
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(MQTTClientComponent),
 | 
			
		||||
    vol.Required(CONF_BROKER): cv.string_strict,
 | 
			
		||||
    vol.Optional(CONF_PORT): cv.port,
 | 
			
		||||
@@ -163,8 +162,8 @@ def to_code(config):
 | 
			
		||||
        else:
 | 
			
		||||
            add(mqtt.set_log_message_template(exp_mqtt_message(log_topic)))
 | 
			
		||||
 | 
			
		||||
            if CONF_LEVEL in config:
 | 
			
		||||
                add(mqtt.set_log_level(logger.LOG_LEVELS[config[CONF_LEVEL]]))
 | 
			
		||||
            if CONF_LEVEL in log_topic:
 | 
			
		||||
                add(mqtt.set_log_level(logger.LOG_LEVELS[log_topic[CONF_LEVEL]]))
 | 
			
		||||
 | 
			
		||||
    if CONF_SSL_FINGERPRINTS in config:
 | 
			
		||||
        for fingerprint in config[CONF_SSL_FINGERPRINTS]:
 | 
			
		||||
@@ -184,16 +183,16 @@ def to_code(config):
 | 
			
		||||
            add(trigger.set_qos(conf[CONF_QOS]))
 | 
			
		||||
        if CONF_PAYLOAD in conf:
 | 
			
		||||
            add(trigger.set_payload(conf[CONF_PAYLOAD]))
 | 
			
		||||
        automation.build_automation(trigger, std_string, conf)
 | 
			
		||||
        automation.build_automations(trigger, [(std_string, 'x')], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_JSON_MESSAGE, []):
 | 
			
		||||
        rhs = mqtt.make_json_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS])
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, JsonObjectConstRef, conf)
 | 
			
		||||
        automation.build_automations(trigger, [(JsonObjectConstRef, 'x')], conf)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_MQTT_PUBLISH = 'mqtt.publish'
 | 
			
		||||
MQTT_PUBLISH_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.use_variable_id(MQTTClientComponent),
 | 
			
		||||
    vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
 | 
			
		||||
    vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
 | 
			
		||||
@@ -203,32 +202,32 @@ MQTT_PUBLISH_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_MQTT_PUBLISH, MQTT_PUBLISH_ACTION_SCHEMA)
 | 
			
		||||
def mqtt_publish_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def mqtt_publish_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_publish_action(template_arg)
 | 
			
		||||
    type = MQTTPublishAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
 | 
			
		||||
    for template_ in templatable(config[CONF_TOPIC], args, std_string):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.set_topic(template_))
 | 
			
		||||
 | 
			
		||||
    for template_ in templatable(config[CONF_PAYLOAD], arg_type, std_string):
 | 
			
		||||
    for template_ in templatable(config[CONF_PAYLOAD], args, std_string):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.set_payload(template_))
 | 
			
		||||
    if CONF_QOS in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_QOS], arg_type, uint8):
 | 
			
		||||
        for template_ in templatable(config[CONF_QOS], args, uint8):
 | 
			
		||||
            yield
 | 
			
		||||
        add(action.set_qos(template_))
 | 
			
		||||
    if CONF_RETAIN in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_RETAIN], arg_type, bool_):
 | 
			
		||||
        for template_ in templatable(config[CONF_RETAIN], args, bool_):
 | 
			
		||||
            yield None
 | 
			
		||||
        add(action.set_retain(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_MQTT_PUBLISH_JSON = 'mqtt.publish_json'
 | 
			
		||||
MQTT_PUBLISH_JSON_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
MQTT_PUBLISH_JSON_ACTION_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.use_variable_id(MQTTClientComponent),
 | 
			
		||||
    vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
 | 
			
		||||
    vol.Required(CONF_PAYLOAD): cv.lambda_,
 | 
			
		||||
@@ -238,18 +237,18 @@ MQTT_PUBLISH_JSON_ACTION_SCHEMA = vol.Schema({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_MQTT_PUBLISH_JSON, MQTT_PUBLISH_JSON_ACTION_SCHEMA)
 | 
			
		||||
def mqtt_publish_json_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def mqtt_publish_json_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_publish_json_action(template_arg)
 | 
			
		||||
    type = MQTTPublishJsonAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
 | 
			
		||||
    for template_ in templatable(config[CONF_TOPIC], args, std_string):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.set_topic(template_))
 | 
			
		||||
 | 
			
		||||
    for lambda_ in process_lambda(config[CONF_PAYLOAD], [(arg_type, 'x'), (JsonObjectRef, 'root')],
 | 
			
		||||
                                  return_type=void):
 | 
			
		||||
    args_ = args + [(JsonObjectRef, 'root')]
 | 
			
		||||
    for lambda_ in process_lambda(config[CONF_PAYLOAD], args_, return_type=void):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.set_payload(lambda_))
 | 
			
		||||
    if CONF_QOS in config:
 | 
			
		||||
@@ -272,61 +271,6 @@ def get_default_topic_for(data, component_type, name, suffix):
 | 
			
		||||
                                sanitized_name, suffix)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_hass_config(data, component_type, config, include_state=True, include_command=True):
 | 
			
		||||
    if config.get(CONF_INTERNAL, False):
 | 
			
		||||
        return None
 | 
			
		||||
    ret = OrderedDict()
 | 
			
		||||
    ret['platform'] = 'mqtt'
 | 
			
		||||
    ret['name'] = config[CONF_NAME]
 | 
			
		||||
    if include_state:
 | 
			
		||||
        default = get_default_topic_for(data, component_type, config[CONF_NAME], 'state')
 | 
			
		||||
        ret['state_topic'] = config.get(CONF_STATE_TOPIC, default)
 | 
			
		||||
    if include_command:
 | 
			
		||||
        default = get_default_topic_for(data, component_type, config[CONF_NAME], 'command')
 | 
			
		||||
        ret['command_topic'] = config.get(CONF_STATE_TOPIC, default)
 | 
			
		||||
    avail = config.get(CONF_AVAILABILITY, data.availability)
 | 
			
		||||
    if avail:
 | 
			
		||||
        ret['availability_topic'] = avail[CONF_TOPIC]
 | 
			
		||||
        payload_available = avail[CONF_PAYLOAD_AVAILABLE]
 | 
			
		||||
        if payload_available != 'online':
 | 
			
		||||
            ret['payload_available'] = payload_available
 | 
			
		||||
        payload_not_available = avail[CONF_PAYLOAD_NOT_AVAILABLE]
 | 
			
		||||
        if payload_not_available != 'offline':
 | 
			
		||||
            ret['payload_not_available'] = payload_not_available
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GenerateHassConfigData(object):
 | 
			
		||||
    def __init__(self, config):
 | 
			
		||||
        if 'mqtt' not in config:
 | 
			
		||||
            raise EsphomeError("Cannot generate Home Assistant MQTT config if MQTT is not "
 | 
			
		||||
                               "used!")
 | 
			
		||||
        mqtt = config[CONF_MQTT]
 | 
			
		||||
        self.topic_prefix = mqtt.get(CONF_TOPIC_PREFIX, config[CONF_ESPHOME][CONF_NAME])
 | 
			
		||||
        birth_message = mqtt.get(CONF_BIRTH_MESSAGE)
 | 
			
		||||
        if CONF_BIRTH_MESSAGE not in mqtt:
 | 
			
		||||
            birth_message = {
 | 
			
		||||
                CONF_TOPIC: self.topic_prefix + '/status',
 | 
			
		||||
                CONF_PAYLOAD: 'online',
 | 
			
		||||
            }
 | 
			
		||||
        will_message = mqtt.get(CONF_WILL_MESSAGE)
 | 
			
		||||
        if CONF_WILL_MESSAGE not in mqtt:
 | 
			
		||||
            will_message = {
 | 
			
		||||
                CONF_TOPIC: self.topic_prefix + '/status',
 | 
			
		||||
                CONF_PAYLOAD: 'offline'
 | 
			
		||||
            }
 | 
			
		||||
        if not birth_message or not will_message:
 | 
			
		||||
            self.availability = None
 | 
			
		||||
        elif birth_message[CONF_TOPIC] != will_message[CONF_TOPIC]:
 | 
			
		||||
            self.availability = None
 | 
			
		||||
        else:
 | 
			
		||||
            self.availability = {
 | 
			
		||||
                CONF_TOPIC: birth_message[CONF_TOPIC],
 | 
			
		||||
                CONF_PAYLOAD_AVAILABLE: birth_message[CONF_PAYLOAD],
 | 
			
		||||
                CONF_PAYLOAD_NOT_AVAILABLE: will_message[CONF_PAYLOAD],
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setup_mqtt_component(obj, config):
 | 
			
		||||
    if CONF_RETAIN in config:
 | 
			
		||||
        add(obj.set_retain(config[CONF_RETAIN]))
 | 
			
		||||
@@ -347,3 +291,13 @@ def setup_mqtt_component(obj, config):
 | 
			
		||||
 | 
			
		||||
LIB_DEPS = 'AsyncMqttClient@0.8.2'
 | 
			
		||||
BUILD_FLAGS = '-DUSE_MQTT'
 | 
			
		||||
 | 
			
		||||
CONF_MQTT_CONNECTED = 'mqtt.connected'
 | 
			
		||||
MQTT_CONNECTED_CONDITION_SCHEMA = cv.Schema({})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_MQTT_CONNECTED, MQTT_CONNECTED_CONDITION_SCHEMA)
 | 
			
		||||
def mqtt_connected_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    rhs = MQTTConnectedCondition.new(template_arg)
 | 
			
		||||
    type = MQTTConnectedCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ from esphome.cpp_types import App, Component
 | 
			
		||||
MY9231OutputComponent = output.output_ns.class_('MY9231OutputComponent', Component)
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(MY9231OutputComponent),
 | 
			
		||||
    vol.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema,
 | 
			
		||||
    vol.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ _LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
OTAComponent = esphome_ns.class_('OTAComponent', Component)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(OTAComponent),
 | 
			
		||||
    vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_PORT): cv.port,
 | 
			
		||||
@@ -51,7 +51,7 @@ REQUIRED_BUILD_FLAGS = '-DUSE_NEW_OTA'
 | 
			
		||||
 | 
			
		||||
def lib_deps(config):
 | 
			
		||||
    if CORE.is_esp32:
 | 
			
		||||
        return ['Update', 'ESPmDNS']
 | 
			
		||||
        return ['Update']
 | 
			
		||||
    if CORE.is_esp8266:
 | 
			
		||||
        return ['Hash', 'ESP8266mDNS']
 | 
			
		||||
        return ['Hash']
 | 
			
		||||
    raise NotImplementedError
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,8 @@ import voluptuous as vol
 | 
			
		||||
from esphome.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
from esphome.components.power_supply import PowerSupplyComponent
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_LEVEL, CONF_MAX_POWER, CONF_POWER_SUPPLY
 | 
			
		||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_LEVEL, CONF_MAX_POWER, \
 | 
			
		||||
    CONF_MIN_POWER, CONF_POWER_SUPPLY
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, get_variable, templatable
 | 
			
		||||
from esphome.cpp_types import Action, esphome_ns, float_
 | 
			
		||||
@@ -12,7 +13,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
BINARY_OUTPUT_SCHEMA = vol.Schema({
 | 
			
		||||
BINARY_OUTPUT_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent),
 | 
			
		||||
    vol.Optional(CONF_INVERTED): cv.boolean,
 | 
			
		||||
})
 | 
			
		||||
@@ -21,6 +22,7 @@ BINARY_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(BINARY_OUTPUT_SCHEMA.sche
 | 
			
		||||
 | 
			
		||||
FLOAT_OUTPUT_SCHEMA = BINARY_OUTPUT_SCHEMA.extend({
 | 
			
		||||
    vol.Optional(CONF_MAX_POWER): cv.percentage,
 | 
			
		||||
    vol.Optional(CONF_MIN_POWER): cv.percentage,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
FLOAT_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FLOAT_OUTPUT_SCHEMA.schema)
 | 
			
		||||
@@ -47,6 +49,8 @@ def setup_output_platform_(obj, config, skip_power_supply=False):
 | 
			
		||||
        add(obj.set_power_supply(power_supply))
 | 
			
		||||
    if CONF_MAX_POWER in config:
 | 
			
		||||
        add(obj.set_max_power(config[CONF_MAX_POWER]))
 | 
			
		||||
    if CONF_MIN_POWER in config:
 | 
			
		||||
        add(obj.set_min_power(config[CONF_MIN_POWER]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setup_output_platform(obj, config, skip_power_supply=False):
 | 
			
		||||
@@ -67,11 +71,11 @@ OUTPUT_TURN_ON_ACTION = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_OUTPUT_TURN_ON, OUTPUT_TURN_ON_ACTION)
 | 
			
		||||
def output_turn_on_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def output_turn_on_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_on_action(template_arg)
 | 
			
		||||
    type = TurnOnAction.template(arg_type)
 | 
			
		||||
    type = TurnOnAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -82,29 +86,29 @@ OUTPUT_TURN_OFF_ACTION = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_OUTPUT_TURN_OFF, OUTPUT_TURN_OFF_ACTION)
 | 
			
		||||
def output_turn_off_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def output_turn_off_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_off_action(template_arg)
 | 
			
		||||
    type = TurnOffAction.template(arg_type)
 | 
			
		||||
    type = TurnOffAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_OUTPUT_SET_LEVEL = 'output.set_level'
 | 
			
		||||
OUTPUT_SET_LEVEL_ACTION = vol.Schema({
 | 
			
		||||
OUTPUT_SET_LEVEL_ACTION = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(FloatOutput),
 | 
			
		||||
    vol.Required(CONF_LEVEL): cv.templatable(cv.percentage),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_OUTPUT_SET_LEVEL, OUTPUT_SET_LEVEL_ACTION)
 | 
			
		||||
def output_set_level_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def output_set_level_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_set_level_action(template_arg)
 | 
			
		||||
    type = SetLevelAction.template(arg_type)
 | 
			
		||||
    type = SetLevelAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
    for template_ in templatable(config[CONF_LEVEL], arg_type, float_):
 | 
			
		||||
    for template_ in templatable(config[CONF_LEVEL], args, float_):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.set_level(template_))
 | 
			
		||||
    yield action
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								esphome/components/output/copy.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								esphome/components/output/copy.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome.components import output
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID, CONF_OUTPUTS, CONF_TYPE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphome.cpp_helpers import setup_component
 | 
			
		||||
 | 
			
		||||
BinaryCopyOutput = output.output_ns.class_('BinaryCopyOutput', output.BinaryOutput)
 | 
			
		||||
FloatCopyOutput = output.output_ns.class_('FloatCopyOutput', output.FloatOutput)
 | 
			
		||||
 | 
			
		||||
BINARY_SCHEMA = output.PLATFORM_SCHEMA.extend({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(BinaryCopyOutput),
 | 
			
		||||
    vol.Required(CONF_TYPE): 'binary',
 | 
			
		||||
    vol.Required(CONF_OUTPUTS): cv.ensure_list(cv.use_variable_id(output.BinaryOutput)),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
FLOAT_SCHEMA = output.PLATFORM_SCHEMA.extend({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(FloatCopyOutput),
 | 
			
		||||
    vol.Required(CONF_TYPE): 'float',
 | 
			
		||||
    vol.Required(CONF_OUTPUTS): cv.ensure_list(cv.use_variable_id(output.FloatOutput)),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_copy_output(value):
 | 
			
		||||
    if not isinstance(value, dict):
 | 
			
		||||
        raise vol.Invalid("Value must be dict")
 | 
			
		||||
    type = cv.string_strict(value.get(CONF_TYPE, 'float')).lower()
 | 
			
		||||
    value[CONF_TYPE] = type
 | 
			
		||||
    if type == 'binary':
 | 
			
		||||
        return BINARY_SCHEMA(value)
 | 
			
		||||
    if type == 'float':
 | 
			
		||||
        return FLOAT_SCHEMA(value)
 | 
			
		||||
    raise vol.Invalid("type must either be binary or float, not {}!".format(type))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = validate_copy_output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    outputs = []
 | 
			
		||||
    for out in config[CONF_OUTPUTS]:
 | 
			
		||||
        for var in get_variable(out):
 | 
			
		||||
            yield
 | 
			
		||||
        outputs.append(var)
 | 
			
		||||
 | 
			
		||||
    klass = {
 | 
			
		||||
        'binary': BinaryCopyOutput,
 | 
			
		||||
        'float': FloatCopyOutput,
 | 
			
		||||
    }[config[CONF_TYPE]]
 | 
			
		||||
    rhs = klass.new(outputs)
 | 
			
		||||
    gpio = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 | 
			
		||||
    output.setup_output_platform(gpio, config)
 | 
			
		||||
    setup_component(gpio, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_COPY_OUTPUT'
 | 
			
		||||
@@ -13,7 +13,7 @@ MULTI_CONF = True
 | 
			
		||||
PCA9685OutputComponent = output.output_ns.class_('PCA9685OutputComponent',
 | 
			
		||||
                                                 Component, i2c.I2CDevice)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(PCA9685OutputComponent),
 | 
			
		||||
    vol.Required(CONF_FREQUENCY): vol.All(cv.frequency,
 | 
			
		||||
                                          vol.Range(min=23.84, max=1525.88)),
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ PCF8675_GPIO_MODES = {
 | 
			
		||||
PCF8574GPIOInputPin = io_ns.class_('PCF8574GPIOInputPin', GPIOInputPin)
 | 
			
		||||
PCF8574GPIOOutputPin = io_ns.class_('PCF8574GPIOOutputPin', GPIOOutputPin)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(pins.PCF8574Component),
 | 
			
		||||
    vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address,
 | 
			
		||||
    vol.Optional(CONF_PCF8575, default=False): cv.boolean,
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ PN532Component = binary_sensor.binary_sensor_ns.class_('PN532Component', Polling
 | 
			
		||||
                                                       spi.SPIDevice)
 | 
			
		||||
PN532Trigger = binary_sensor.binary_sensor_ns.class_('PN532Trigger', Trigger.template(std_string))
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(PN532Component),
 | 
			
		||||
    cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
 | 
			
		||||
    vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
 | 
			
		||||
@@ -38,7 +38,7 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
    for conf_ in config.get(CONF_ON_TAG, []):
 | 
			
		||||
        trigger = Pvariable(conf_[CONF_TRIGGER_ID], pn532.make_trigger())
 | 
			
		||||
        automation.build_automation(trigger, std_string, conf_)
 | 
			
		||||
        automation.build_automations(trigger, [(std_string, 'x')], conf_)
 | 
			
		||||
 | 
			
		||||
    setup_component(pn532, config)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ PowerSupplyComponent = esphome_ns.class_('PowerSupplyComponent', Component)
 | 
			
		||||
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(PowerSupplyComponent),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
 | 
			
		||||
    vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period_milliseconds,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome.components import binary_sensor, uart
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID, CONF_UART_ID
 | 
			
		||||
@@ -12,7 +10,7 @@ DEPENDENCIES = ['uart']
 | 
			
		||||
RDM6300Component = binary_sensor.binary_sensor_ns.class_('RDM6300Component', Component,
 | 
			
		||||
                                                         uart.UARTDevice)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(RDM6300Component),
 | 
			
		||||
    cv.GenerateID(CONF_UART_ID): cv.use_variable_id(uart.UARTComponent),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,9 +40,10 @@ def validate_dumpers_all(value):
 | 
			
		||||
    raise vol.Invalid("Not valid dumpers")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(RemoteReceiverComponent),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.gpio_input_pin_schema,
 | 
			
		||||
    vol.Required(CONF_PIN): vol.All(pins.internal_gpio_input_pin_schema,
 | 
			
		||||
                                    pins.validate_has_interrupt),
 | 
			
		||||
    vol.Optional(CONF_DUMP, default=[]):
 | 
			
		||||
        vol.Any(validate_dumpers_all, cv.ensure_list(cv.one_of(*DUMPERS, lower=True))),
 | 
			
		||||
    vol.Optional(CONF_TOLERANCE): vol.All(cv.percentage_int, vol.Range(min=0)),
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ RC_SWITCH_TIMING_SCHEMA = vol.All([cv.uint8_t], vol.Length(min=2, max=2))
 | 
			
		||||
 | 
			
		||||
RC_SWITCH_PROTOCOL_SCHEMA = vol.Any(
 | 
			
		||||
    vol.All(vol.Coerce(int), vol.Range(min=1, max=7)),
 | 
			
		||||
    vol.Schema({
 | 
			
		||||
    cv.Schema({
 | 
			
		||||
        vol.Required(CONF_PULSE_LENGTH): cv.uint32_t,
 | 
			
		||||
        vol.Optional(CONF_SYNC, default=[1, 31]): RC_SWITCH_TIMING_SCHEMA,
 | 
			
		||||
        vol.Optional(CONF_ZERO, default=[1, 3]): RC_SWITCH_TIMING_SCHEMA,
 | 
			
		||||
@@ -48,23 +48,23 @@ RC_SWITCH_PROTOCOL_SCHEMA = vol.Any(
 | 
			
		||||
    })
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
RC_SWITCH_RAW_SCHEMA = vol.Schema({
 | 
			
		||||
RC_SWITCH_RAW_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_CODE): validate_rc_switch_code,
 | 
			
		||||
    vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
 | 
			
		||||
})
 | 
			
		||||
RC_SWITCH_TYPE_A_SCHEMA = vol.Schema({
 | 
			
		||||
RC_SWITCH_TYPE_A_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_GROUP): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)),
 | 
			
		||||
    vol.Required(CONF_DEVICE): vol.All(validate_rc_switch_code, vol.Length(min=5, max=5)),
 | 
			
		||||
    vol.Required(CONF_STATE): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
 | 
			
		||||
})
 | 
			
		||||
RC_SWITCH_TYPE_B_SCHEMA = vol.Schema({
 | 
			
		||||
RC_SWITCH_TYPE_B_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_ADDRESS): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
 | 
			
		||||
    vol.Required(CONF_CHANNEL): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
 | 
			
		||||
    vol.Required(CONF_STATE): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
 | 
			
		||||
})
 | 
			
		||||
RC_SWITCH_TYPE_C_SCHEMA = vol.Schema({
 | 
			
		||||
RC_SWITCH_TYPE_C_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_FAMILY): cv.one_of('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
 | 
			
		||||
                                         'l', 'm', 'n', 'o', 'p', lower=True),
 | 
			
		||||
    vol.Required(CONF_GROUP): vol.All(cv.uint8_t, vol.Range(min=1, max=4)),
 | 
			
		||||
@@ -72,14 +72,14 @@ RC_SWITCH_TYPE_C_SCHEMA = vol.Schema({
 | 
			
		||||
    vol.Required(CONF_STATE): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
 | 
			
		||||
})
 | 
			
		||||
RC_SWITCH_TYPE_D_SCHEMA = vol.Schema({
 | 
			
		||||
RC_SWITCH_TYPE_D_SCHEMA = cv.Schema({
 | 
			
		||||
    vol.Required(CONF_GROUP): cv.one_of('a', 'b', 'c', 'd', lower=True),
 | 
			
		||||
    vol.Required(CONF_DEVICE): vol.All(cv.uint8_t, vol.Range(min=1, max=3)),
 | 
			
		||||
    vol.Required(CONF_STATE): cv.boolean,
 | 
			
		||||
    vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = cv.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(RemoteTransmitterComponent),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
 | 
			
		||||
    vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(cv.percentage_int,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@ from esphome.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID
 | 
			
		||||
from esphome.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphome.cpp_types import Action, NoArg, Trigger, esphome_ns
 | 
			
		||||
from esphome.cpp_types import Action, Trigger, esphome_ns
 | 
			
		||||
 | 
			
		||||
Script = esphome_ns.class_('Script', Trigger.template(NoArg))
 | 
			
		||||
Script = esphome_ns.class_('Script', Trigger.template())
 | 
			
		||||
ScriptExecuteAction = esphome_ns.class_('ScriptExecuteAction', Action)
 | 
			
		||||
ScriptStopAction = esphome_ns.class_('ScriptStopAction', Action)
 | 
			
		||||
 | 
			
		||||
@@ -19,7 +19,7 @@ CONFIG_SCHEMA = automation.validate_automation({
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        trigger = Pvariable(conf[CONF_ID], Script.new())
 | 
			
		||||
        automation.build_automation(trigger, NoArg, conf)
 | 
			
		||||
        automation.build_automations(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_SCRIPT_EXECUTE = 'script.execute'
 | 
			
		||||
@@ -29,11 +29,11 @@ SCRIPT_EXECUTE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_SCRIPT_EXECUTE, SCRIPT_EXECUTE_ACTION_SCHEMA)
 | 
			
		||||
def script_execute_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def script_execute_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_execute_action(template_arg)
 | 
			
		||||
    type = ScriptExecuteAction.template(arg_type)
 | 
			
		||||
    type = ScriptExecuteAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -44,9 +44,9 @@ SCRIPT_STOP_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_SCRIPT_STOP, SCRIPT_STOP_ACTION_SCHEMA)
 | 
			
		||||
def script_stop_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
def script_stop_action_to_code(config, action_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_stop_action(template_arg)
 | 
			
		||||
    type = ScriptStopAction.template(arg_type)
 | 
			
		||||
    type = ScriptStopAction.template(template_arg)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
import math
 | 
			
		||||
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphome import automation
 | 
			
		||||
@@ -6,12 +8,13 @@ from esphome.components import mqtt
 | 
			
		||||
from esphome.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
 | 
			
		||||
    CONF_DEBOUNCE, CONF_DELTA, CONF_EXPIRE_AFTER, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, \
 | 
			
		||||
    CONF_FILTER_NAN, CONF_FILTER_OUT, CONF_HEARTBEAT, CONF_ICON, CONF_ID, CONF_INTERNAL, \
 | 
			
		||||
    CONF_LAMBDA, CONF_MQTT_ID, CONF_MULTIPLY, CONF_OFFSET, CONF_ON_RAW_VALUE, CONF_ON_VALUE, \
 | 
			
		||||
    CONF_ON_VALUE_RANGE, CONF_OR, CONF_SEND_EVERY, CONF_SEND_FIRST_AT, \
 | 
			
		||||
    CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_THROTTLE, CONF_TRIGGER_ID, CONF_UNIQUE, \
 | 
			
		||||
    CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE
 | 
			
		||||
    CONF_CALIBRATE_LINEAR, CONF_DEBOUNCE, CONF_DELTA, CONF_EXPIRE_AFTER, \
 | 
			
		||||
    CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, CONF_FILTER_OUT, CONF_FROM, \
 | 
			
		||||
    CONF_HEARTBEAT, CONF_ICON, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, \
 | 
			
		||||
    CONF_MULTIPLY, CONF_OFFSET, CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, CONF_OR, \
 | 
			
		||||
    CONF_SEND_EVERY, CONF_SEND_FIRST_AT, CONF_SLIDING_WINDOW_MOVING_AVERAGE, \
 | 
			
		||||
    CONF_THROTTLE, CONF_TO, CONF_TRIGGER_ID, CONF_UNIQUE, CONF_UNIT_OF_MEASUREMENT, \
 | 
			
		||||
    CONF_WINDOW_SIZE
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
 | 
			
		||||
from esphome.cpp_types import App, Component, Nameable, PollingComponent, Trigger, \
 | 
			
		||||
@@ -35,28 +38,51 @@ def validate_send_first_at(value):
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FILTER_KEYS = [CONF_OFFSET, CONF_MULTIPLY, CONF_FILTER_OUT, CONF_FILTER_NAN,
 | 
			
		||||
FILTER_KEYS = [CONF_OFFSET, CONF_MULTIPLY, CONF_FILTER_OUT,
 | 
			
		||||
               CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_LAMBDA,
 | 
			
		||||
               CONF_THROTTLE, CONF_DELTA, CONF_UNIQUE, CONF_HEARTBEAT, CONF_DEBOUNCE, CONF_OR]
 | 
			
		||||
               CONF_THROTTLE, CONF_DELTA, CONF_HEARTBEAT, CONF_DEBOUNCE, CONF_OR,
 | 
			
		||||
               CONF_CALIBRATE_LINEAR]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_datapoint(value):
 | 
			
		||||
    if isinstance(value, dict):
 | 
			
		||||
        return cv.Schema({
 | 
			
		||||
            vol.Required(CONF_FROM): cv.float_,
 | 
			
		||||
            vol.Required(CONF_TO): cv.float_,
 | 
			
		||||
        })(value)
 | 
			
		||||
    value = cv.string(value)
 | 
			
		||||
    if '->' not in value:
 | 
			
		||||
        raise vol.Invalid("Datapoint mapping must contain '->'")
 | 
			
		||||
    a, b = value.split('->', 1)
 | 
			
		||||
    a, b = a.strip(), b.strip()
 | 
			
		||||
    return validate_datapoint({
 | 
			
		||||
        CONF_FROM: cv.float_(a),
 | 
			
		||||
        CONF_TO: cv.float_(b)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FILTERS_SCHEMA = cv.ensure_list({
 | 
			
		||||
    vol.Optional(CONF_OFFSET): cv.float_,
 | 
			
		||||
    vol.Optional(CONF_MULTIPLY): cv.float_,
 | 
			
		||||
    vol.Optional(CONF_FILTER_OUT): cv.float_,
 | 
			
		||||
    vol.Optional(CONF_FILTER_NAN): None,
 | 
			
		||||
    vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.All(vol.Schema({
 | 
			
		||||
    vol.Optional('filter_nan'): cv.invalid("The filter_nan filter has been removed. Please use "
 | 
			
		||||
                                           "'filter_out: nan' instead"),
 | 
			
		||||
    vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.All(cv.Schema({
 | 
			
		||||
        vol.Optional(CONF_WINDOW_SIZE, default=15): cv.positive_not_null_int,
 | 
			
		||||
        vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
 | 
			
		||||
        vol.Optional(CONF_SEND_FIRST_AT): cv.positive_not_null_int,
 | 
			
		||||
    }), validate_send_first_at),
 | 
			
		||||
    vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): cv.Schema({
 | 
			
		||||
        vol.Optional(CONF_ALPHA, default=0.1): cv.positive_float,
 | 
			
		||||
        vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_CALIBRATE_LINEAR): vol.All(
 | 
			
		||||
        cv.ensure_list(validate_datapoint), vol.Length(min=2)),
 | 
			
		||||
    vol.Optional(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Optional(CONF_THROTTLE): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_DELTA): cv.float_,
 | 
			
		||||
    vol.Optional(CONF_UNIQUE): None,
 | 
			
		||||
    vol.Optional(CONF_UNIQUE): cv.invalid("The unique filter has been removed in 1.12, please "
 | 
			
		||||
                                          "replace with a delta filter with small value."),
 | 
			
		||||
    vol.Optional(CONF_HEARTBEAT): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_DEBOUNCE): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_OR): validate_recursive_filter,
 | 
			
		||||
@@ -85,13 +111,12 @@ LambdaFilter = sensor_ns.class_('LambdaFilter', Filter)
 | 
			
		||||
OffsetFilter = sensor_ns.class_('OffsetFilter', Filter)
 | 
			
		||||
MultiplyFilter = sensor_ns.class_('MultiplyFilter', Filter)
 | 
			
		||||
FilterOutValueFilter = sensor_ns.class_('FilterOutValueFilter', Filter)
 | 
			
		||||
FilterOutNANFilter = sensor_ns.class_('FilterOutNANFilter', Filter)
 | 
			
		||||
ThrottleFilter = sensor_ns.class_('ThrottleFilter', Filter)
 | 
			
		||||
DebounceFilter = sensor_ns.class_('DebounceFilter', Filter, Component)
 | 
			
		||||
HeartbeatFilter = sensor_ns.class_('HeartbeatFilter', Filter, Component)
 | 
			
		||||
DeltaFilter = sensor_ns.class_('DeltaFilter', Filter)
 | 
			
		||||
OrFilter = sensor_ns.class_('OrFilter', Filter)
 | 
			
		||||
UniqueFilter = sensor_ns.class_('UniqueFilter', Filter)
 | 
			
		||||
CalibrateLinearFilter = sensor_ns.class_('CalibrateLinearFilter', Filter)
 | 
			
		||||
SensorInRangeCondition = sensor_ns.class_('SensorInRangeCondition', Filter)
 | 
			
		||||
 | 
			
		||||
SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
 | 
			
		||||
@@ -125,8 +150,6 @@ def setup_filter(config):
 | 
			
		||||
        yield MultiplyFilter.new(config[CONF_MULTIPLY])
 | 
			
		||||
    elif CONF_FILTER_OUT in config:
 | 
			
		||||
        yield FilterOutValueFilter.new(config[CONF_FILTER_OUT])
 | 
			
		||||
    elif CONF_FILTER_NAN in config:
 | 
			
		||||
        yield FilterOutNANFilter.new()
 | 
			
		||||
    elif CONF_SLIDING_WINDOW_MOVING_AVERAGE in config:
 | 
			
		||||
        conf = config[CONF_SLIDING_WINDOW_MOVING_AVERAGE]
 | 
			
		||||
        yield SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY],
 | 
			
		||||
@@ -151,8 +174,11 @@ def setup_filter(config):
 | 
			
		||||
        yield App.register_component(HeartbeatFilter.new(config[CONF_HEARTBEAT]))
 | 
			
		||||
    elif CONF_DEBOUNCE in config:
 | 
			
		||||
        yield App.register_component(DebounceFilter.new(config[CONF_DEBOUNCE]))
 | 
			
		||||
    elif CONF_UNIQUE in config:
 | 
			
		||||
        yield UniqueFilter.new()
 | 
			
		||||
    elif CONF_CALIBRATE_LINEAR in config:
 | 
			
		||||
        x = [conf[CONF_FROM] for conf in config[CONF_CALIBRATE_LINEAR]]
 | 
			
		||||
        y = [conf[CONF_TO] for conf in config[CONF_CALIBRATE_LINEAR]]
 | 
			
		||||
        k, b = fit_linear(x, y)
 | 
			
		||||
        yield CalibrateLinearFilter.new(k, b)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setup_filters(config):
 | 
			
		||||
@@ -181,11 +207,11 @@ def setup_sensor_core_(sensor_var, config):
 | 
			
		||||
    for conf in config.get(CONF_ON_VALUE, []):
 | 
			
		||||
        rhs = sensor_var.make_state_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, float_, conf)
 | 
			
		||||
        automation.build_automations(trigger, [(float_, 'x')], conf)
 | 
			
		||||
    for conf in config.get(CONF_ON_RAW_VALUE, []):
 | 
			
		||||
        rhs = sensor_var.make_raw_state_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        automation.build_automation(trigger, float_, conf)
 | 
			
		||||
        automation.build_automations(trigger, [(float_, 'x')], conf)
 | 
			
		||||
    for conf in config.get(CONF_ON_VALUE_RANGE, []):
 | 
			
		||||
        rhs = sensor_var.make_value_range_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
@@ -198,7 +224,7 @@ def setup_sensor_core_(sensor_var, config):
 | 
			
		||||
            for template_ in templatable(conf[CONF_BELOW], float_, float_):
 | 
			
		||||
                yield
 | 
			
		||||
            add(trigger.set_max(template_))
 | 
			
		||||
        automation.build_automation(trigger, float_, conf)
 | 
			
		||||
        automation.build_automations(trigger, [(float_, 'x')], conf)
 | 
			
		||||
 | 
			
		||||
    mqtt_ = sensor_var.Pget_mqtt()
 | 
			
		||||
    if CONF_EXPIRE_AFTER in config:
 | 
			
		||||
@@ -232,11 +258,11 @@ SENSOR_IN_RANGE_CONDITION_SCHEMA = vol.All({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@CONDITION_REGISTRY.register(CONF_SENSOR_IN_RANGE, SENSOR_IN_RANGE_CONDITION_SCHEMA)
 | 
			
		||||
def sensor_in_range_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
def sensor_in_range_to_code(config, condition_id, template_arg, args):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_sensor_in_range_condition(template_arg)
 | 
			
		||||
    type = SensorInRangeCondition.template(arg_type)
 | 
			
		||||
    type = SensorInRangeCondition.template(template_arg)
 | 
			
		||||
    cond = Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
    if CONF_ABOVE in config:
 | 
			
		||||
@@ -247,16 +273,26 @@ def sensor_in_range_to_code(config, condition_id, arg_type, template_arg):
 | 
			
		||||
    yield cond
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def core_to_hass_config(data, config):
 | 
			
		||||
    ret = mqtt.build_hass_config(data, 'sensor', config, include_state=True, include_command=False)
 | 
			
		||||
    if ret is None:
 | 
			
		||||
        return None
 | 
			
		||||
    if CONF_UNIT_OF_MEASUREMENT in config:
 | 
			
		||||
        ret['unit_of_measurement'] = config[CONF_UNIT_OF_MEASUREMENT]
 | 
			
		||||
    if CONF_EXPIRE_AFTER in config:
 | 
			
		||||
        expire = config[CONF_EXPIRE_AFTER]
 | 
			
		||||
        if expire is not None:
 | 
			
		||||
            ret['expire_after'] = expire.total_seconds
 | 
			
		||||
    if CONF_ICON in config:
 | 
			
		||||
        ret['icon'] = config[CONF_ICON]
 | 
			
		||||
    return ret
 | 
			
		||||
def _mean(xs):
 | 
			
		||||
    return sum(xs) / len(xs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _std(x):
 | 
			
		||||
    return math.sqrt(sum((x_ - _mean(x))**2 for x_ in x) / (len(x) - 1))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _correlation_coeff(x, y):
 | 
			
		||||
    m_x, m_y = _mean(x), _mean(y)
 | 
			
		||||
    s_xy = sum((x_ - m_x) * (y_ - m_y) for x_, y_ in zip(x, y))
 | 
			
		||||
    s_sq_x = sum((x_ - m_x)**2 for x_ in x)
 | 
			
		||||
    s_sq_y = sum((y_ - m_y)**2 for y_ in y)
 | 
			
		||||
    return s_xy / math.sqrt(s_sq_x * s_sq_y)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fit_linear(x, y):
 | 
			
		||||
    assert len(x) == len(y)
 | 
			
		||||
    m_x, m_y = _mean(x), _mean(y)
 | 
			
		||||
    r = _correlation_coeff(x, y)
 | 
			
		||||
    k = r * (_std(y) / _std(x))
 | 
			
		||||
    b = m_y - k * m_x
 | 
			
		||||
    return k, b
 | 
			
		||||
 
 | 
			
		||||
@@ -56,10 +56,6 @@ def required_build_flags(config):
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def includes(config):
 | 
			
		||||
    if config[CONF_PIN] == 'VCC':
 | 
			
		||||
        return 'ADC_MODE(ADC_VCC);'
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ MUX = {
 | 
			
		||||
ADS1115Gain = sensor.sensor_ns.enum('ADS1115Gain')
 | 
			
		||||
GAIN = {
 | 
			
		||||
    '6.144': ADS1115Gain.ADS1115_GAIN_6P144,
 | 
			
		||||
    '4.096': ADS1115Gain.ADS1115_GAIN_6P096,
 | 
			
		||||
    '4.096': ADS1115Gain.ADS1115_GAIN_4P096,
 | 
			
		||||
    '2.048': ADS1115Gain.ADS1115_GAIN_2P048,
 | 
			
		||||
    '1.024': ADS1115Gain.ADS1115_GAIN_1P024,
 | 
			
		||||
    '0.512': ADS1115Gain.ADS1115_GAIN_0P512,
 | 
			
		||||
@@ -70,7 +70,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,3 @@ def to_code(config):
 | 
			
		||||
    func = getattr(hub, TYPES[config[CONF_TYPE]])
 | 
			
		||||
    rhs = func(config[CONF_NAME])
 | 
			
		||||
    sensor.register_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_BH1750'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,3 @@ def to_code(config):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = hub.make_rssi_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
 | 
			
		||||
    sensor.register_sensor(rhs, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -85,9 +85,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_BME280'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_PRESSURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
 | 
			
		||||
        cv.GenerateID(): cv.declare_variable_id(BME680GasResistanceSensor),
 | 
			
		||||
    })),
 | 
			
		||||
    vol.Optional(CONF_IIR_FILTER): cv.one_of(*IIR_FILTER_OPTIONS, upper=True),
 | 
			
		||||
    vol.Optional(CONF_HEATER): vol.Any(None, vol.All(vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_HEATER): vol.Any(None, vol.All(cv.Schema({
 | 
			
		||||
        vol.Optional(CONF_TEMPERATURE, default=320): vol.All(vol.Coerce(int), vol.Range(200, 400)),
 | 
			
		||||
        vol.Optional(CONF_DURATION, default='150ms'): vol.All(
 | 
			
		||||
            cv.positive_time_period_milliseconds, vol.Range(max=core.TimePeriod(milliseconds=4032)))
 | 
			
		||||
@@ -108,10 +108,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_BME680'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_PRESSURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_HUMIDITY]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_GAS_RESISTANCE])]
 | 
			
		||||
 
 | 
			
		||||
@@ -43,8 +43,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_BMP085_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_PRESSURE])]
 | 
			
		||||
 
 | 
			
		||||
@@ -75,8 +75,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_BMP280'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_PRESSURE])]
 | 
			
		||||
 
 | 
			
		||||
@@ -57,11 +57,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_CSE7766'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    ret = []
 | 
			
		||||
    for key in (CONF_VOLTAGE, CONF_CURRENT, CONF_POWER):
 | 
			
		||||
        if key in config:
 | 
			
		||||
            ret.append(sensor.core_to_hass_config(data, config[key]))
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ import voluptuous as vol
 | 
			
		||||
from esphome.components import sensor
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_SENSORS
 | 
			
		||||
from esphome.cpp_generator import Pvariable, add, process_lambda, variable
 | 
			
		||||
from esphome.cpp_generator import add, process_lambda, variable
 | 
			
		||||
from esphome.cpp_types import std_vector
 | 
			
		||||
 | 
			
		||||
CustomSensorConstructor = sensor.sensor_ns.class_('CustomSensorConstructor')
 | 
			
		||||
@@ -25,13 +25,9 @@ def to_code(config):
 | 
			
		||||
    rhs = CustomSensorConstructor(template_)
 | 
			
		||||
    custom = variable(config[CONF_ID], rhs)
 | 
			
		||||
    for i, conf in enumerate(config[CONF_SENSORS]):
 | 
			
		||||
        var = Pvariable(conf[CONF_ID], custom.get_sensor(i))
 | 
			
		||||
        add(var.set_name(conf[CONF_NAME]))
 | 
			
		||||
        sensor.setup_sensor(var, conf)
 | 
			
		||||
        rhs = custom.Pget_sensor(i)
 | 
			
		||||
        add(rhs.set_name(conf[CONF_NAME]))
 | 
			
		||||
        sensor.register_sensor(rhs, conf)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_CUSTOM_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, sens) for sens in config[CONF_SENSORS]]
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -57,8 +57,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_DHT_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_DHT12_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,8 @@ DutyCycleSensor = sensor.sensor_ns.class_('DutyCycleSensor', sensor.PollingSenso
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(DutyCycleSensor),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.internal_gpio_input_pin_schema,
 | 
			
		||||
    vol.Required(CONF_PIN): vol.All(pins.internal_gpio_input_pin_schema,
 | 
			
		||||
                                    pins.validate_has_interrupt),
 | 
			
		||||
    vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema))
 | 
			
		||||
 | 
			
		||||
@@ -28,7 +29,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_DUTY_CYCLE_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_ESP32_HALL_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return sensor.core_to_hass_config(data, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_HDC1080_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
 | 
			
		||||
            sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
 | 
			
		||||
 
 | 
			
		||||
@@ -66,11 +66,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_HLW8012'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    ret = []
 | 
			
		||||
    for key in (CONF_VOLTAGE, CONF_CURRENT, CONF_POWER):
 | 
			
		||||
        if key in config:
 | 
			
		||||
            ret.append(sensor.core_to_hass_config(data, config[key]))
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
@@ -87,11 +87,3 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_HMC5883L'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_hass_config(data, config):
 | 
			
		||||
    ret = []
 | 
			
		||||
    for key in (CONF_FIELD_STRENGTH_X, CONF_FIELD_STRENGTH_Y, CONF_FIELD_STRENGTH_Z, CONF_HEADING):
 | 
			
		||||
        if key in config:
 | 
			
		||||
            ret.append(sensor.core_to_hass_config(data, config[key]))
 | 
			
		||||
    return ret
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user