mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	[Huge] Util Refactor, Dashboard Improvements, Hass.io Auth API, Better Validation Errors, Conditions, Custom Platforms, Substitutions (#234)
* Implement custom sensor platform
* Update
* Ethernet
* Lint
* Fix
* Login page
* Rename cookie secret
* Update manifest
* Update cookie check logic
* Favicon
* Fix
* Favicon manifest
* Fix
* Fix
* Fix
* Use hostname
* Message
* Temporary commit for screenshot
* Automatic board selection
* Undo temporary commit
* Update esphomeyaml-edge
* In-dashboard editing and hosting files locally
* Update esphomeyaml-edge
* Better ANSI color escaping
* Message
* Lint
* Download Efficiency
* Fix gitlab
* Fix
* Rename extra_libraries to libraries
* Add example
* Update README.md
* Update README.md
* Update README.md
* HassIO -> Hass.io
* Updates
* Add update available notice
* Update
* Fix substitutions
* Better error message
* Re-do dashboard ANSI colors
* Only include FastLED if user says so
* Autoscroll logs
* Remove old checks
* Use safer RedirectText
* Improvements
* Fix
* Use enviornment variable
* Use http://hassio/host/info
* Fix conditions
* Update platformio versions
* Revert "Use enviornment variable"
This reverts commit 7f038eb5d2.
* Fix
* README update
* Temp
* Better invalid config messages
* Platformio debug
* Improve error messages
* Debug
* Remove debug
* Multi Conf
* Update
* Better paths
* Remove unused
* Fixes
* Lint
* lib_ignore
* Try fix platformio colors
* Fix dashboard scrolling
* Revert
* Lint
* Revert
			
			
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -105,3 +105,4 @@ venv.bak/
 | 
			
		||||
 | 
			
		||||
config/
 | 
			
		||||
tests/build/
 | 
			
		||||
tests/.esphomeyaml/
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,8 @@ stages:
 | 
			
		||||
 | 
			
		||||
.lint: &lint
 | 
			
		||||
  stage: lint
 | 
			
		||||
  before_script:
 | 
			
		||||
    - pip install -e .
 | 
			
		||||
  tags:
 | 
			
		||||
    - python2.7
 | 
			
		||||
    - esphomeyaml-lint
 | 
			
		||||
@@ -24,9 +26,6 @@ stages:
 | 
			
		||||
    - esphomeyaml-test
 | 
			
		||||
  variables:
 | 
			
		||||
    TZ: UTC
 | 
			
		||||
  cache:
 | 
			
		||||
    paths:
 | 
			
		||||
      - tests/build
 | 
			
		||||
 | 
			
		||||
.docker-builder: &docker-builder
 | 
			
		||||
  before_script:
 | 
			
		||||
@@ -62,21 +61,20 @@ test2:
 | 
			
		||||
  stage: build
 | 
			
		||||
  script:
 | 
			
		||||
    - docker run --rm --privileged hassioaddons/qemu-user-static:latest
 | 
			
		||||
    - BUILD_FROM=homeassistant/${ADDON_ARCH}-base-ubuntu:latest
 | 
			
		||||
    - BUILD_FROM=hassioaddons/ubuntu-base-${ADDON_ARCH}:2.2.0
 | 
			
		||||
    - ADDON_VERSION="${CI_COMMIT_TAG#v}"
 | 
			
		||||
    - ADDON_VERSION="${ADDON_VERSION:-${CI_COMMIT_SHA:0:7}}"
 | 
			
		||||
    - ESPHOMELIB_VERSION="${ESPHOMELIB_VERSION:-''}"
 | 
			
		||||
    - echo "Build from ${BUILD_FROM}"
 | 
			
		||||
    - echo "Add-on version ${ADDON_VERSION}"
 | 
			
		||||
    - echo "Esphomelib version ${ESPHOMELIB_VERSION}"
 | 
			
		||||
    - echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:dev"
 | 
			
		||||
    - echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
 | 
			
		||||
    - |
 | 
			
		||||
      docker build \
 | 
			
		||||
        --build-arg "BUILD_FROM=${BUILD_FROM}" \
 | 
			
		||||
        --build-arg "ADDON_ARCH=${ADDON_ARCH}" \
 | 
			
		||||
        --build-arg "ADDON_VERSION=${ADDON_VERSION}" \
 | 
			
		||||
        --build-arg "ESPHOMELIB_VERSION=${ESPHOMELIB_VERSION}" \
 | 
			
		||||
        --build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \
 | 
			
		||||
        --build-arg "BUILD_ARCH=${ADDON_ARCH}" \
 | 
			
		||||
        --build-arg "BUILD_REF=${CI_COMMIT_SHA}" \
 | 
			
		||||
        --build-arg "BUILD_VERSION=${ADDON_VERSION}" \
 | 
			
		||||
        --tag "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:dev" \
 | 
			
		||||
        --tag "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
 | 
			
		||||
        --file "docker/Dockerfile.hassio" \
 | 
			
		||||
@@ -209,31 +207,28 @@ build:hassio-armhf-edge:
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: armhf
 | 
			
		||||
    DO_PUSH: "false"
 | 
			
		||||
    ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
 | 
			
		||||
 | 
			
		||||
build:hassio-armhf:
 | 
			
		||||
  <<: *build-hassio-release
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: armhf
 | 
			
		||||
 | 
			
		||||
build:hassio-aarch64-edge:
 | 
			
		||||
  <<: *build-hassio-edge
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: aarch64
 | 
			
		||||
    DO_PUSH: "false"
 | 
			
		||||
    ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
 | 
			
		||||
#build:hassio-aarch64-edge:
 | 
			
		||||
#  <<: *build-hassio-edge
 | 
			
		||||
#  variables:
 | 
			
		||||
#    ADDON_ARCH: aarch64
 | 
			
		||||
#    DO_PUSH: "false"
 | 
			
		||||
 | 
			
		||||
build:hassio-aarch64:
 | 
			
		||||
  <<: *build-hassio-release
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: aarch64
 | 
			
		||||
#build:hassio-aarch64:
 | 
			
		||||
#  <<: *build-hassio-release
 | 
			
		||||
#  variables:
 | 
			
		||||
#    ADDON_ARCH: aarch64
 | 
			
		||||
 | 
			
		||||
build:hassio-i386-edge:
 | 
			
		||||
  <<: *build-hassio-edge
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: i386
 | 
			
		||||
    DO_PUSH: "false"
 | 
			
		||||
    ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
 | 
			
		||||
 | 
			
		||||
build:hassio-i386:
 | 
			
		||||
  <<: *build-hassio-release
 | 
			
		||||
@@ -245,7 +240,6 @@ build:hassio-amd64-edge:
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: amd64
 | 
			
		||||
    DO_PUSH: "false"
 | 
			
		||||
    ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
 | 
			
		||||
 | 
			
		||||
build:hassio-amd64:
 | 
			
		||||
  <<: *build-hassio-release
 | 
			
		||||
@@ -263,15 +257,15 @@ deploy-beta:armhf:
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: armhf
 | 
			
		||||
 | 
			
		||||
deploy-release:aarch64:
 | 
			
		||||
  <<: *deploy-release
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: aarch64
 | 
			
		||||
#deploy-release:aarch64:
 | 
			
		||||
#  <<: *deploy-release
 | 
			
		||||
#  variables:
 | 
			
		||||
#    ADDON_ARCH: aarch64
 | 
			
		||||
 | 
			
		||||
deploy-beta:aarch64:
 | 
			
		||||
  <<: *deploy-beta
 | 
			
		||||
  variables:
 | 
			
		||||
    ADDON_ARCH: aarch64
 | 
			
		||||
#deploy-beta:aarch64:
 | 
			
		||||
#  <<: *deploy-beta
 | 
			
		||||
#  variables:
 | 
			
		||||
#    ADDON_ARCH: aarch64
 | 
			
		||||
 | 
			
		||||
deploy-release:i386:
 | 
			
		||||
  <<: *deploy-release
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								MANIFEST.in
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								MANIFEST.in
									
									
									
									
									
								
							@@ -1,4 +1,16 @@
 | 
			
		||||
include README.md
 | 
			
		||||
include esphomeyaml/dashboard/templates/index.html
 | 
			
		||||
include esphomeyaml/dashboard/templates/login.html
 | 
			
		||||
include esphomeyaml/dashboard/static/ace.js
 | 
			
		||||
include esphomeyaml/dashboard/static/esphomeyaml.css
 | 
			
		||||
include esphomeyaml/dashboard/static/esphomeyaml.js
 | 
			
		||||
include esphomeyaml/dashboard/static/favicon.ico
 | 
			
		||||
include esphomeyaml/dashboard/static/jquery.min.js
 | 
			
		||||
include esphomeyaml/dashboard/static/jquery.validate.min.js
 | 
			
		||||
include esphomeyaml/dashboard/static/jquery-ui.min.js
 | 
			
		||||
include esphomeyaml/dashboard/static/materialize.min.css
 | 
			
		||||
include esphomeyaml/dashboard/static/materialize.min.js
 | 
			
		||||
include esphomeyaml/dashboard/static/materialize-stepper.min.css
 | 
			
		||||
include esphomeyaml/dashboard/static/materialize-stepper.min.js
 | 
			
		||||
include esphomeyaml/dashboard/static/mode-yaml.js
 | 
			
		||||
include esphomeyaml/dashboard/static/theme-dreamweaver.js
 | 
			
		||||
 
 | 
			
		||||
@@ -1,40 +1,78 @@
 | 
			
		||||
# Dockerfile for HassIO add-on
 | 
			
		||||
ARG BUILD_FROM=homeassistant/amd64-base-ubuntu:latest
 | 
			
		||||
ARG BUILD_FROM=hassioaddons/ubuntu-base:2.2.0
 | 
			
		||||
# hadolint ignore=DL3006
 | 
			
		||||
FROM ${BUILD_FROM}
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get install -y --no-install-recommends \
 | 
			
		||||
# Set shell
 | 
			
		||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
 | 
			
		||||
 | 
			
		||||
# Copy root filesystem
 | 
			
		||||
COPY esphomeyaml-edge/rootfs /
 | 
			
		||||
COPY setup.py setup.cfg MANIFEST.in /opt/esphomeyaml/
 | 
			
		||||
COPY esphomeyaml /opt/esphomeyaml/esphomeyaml
 | 
			
		||||
 | 
			
		||||
RUN \
 | 
			
		||||
    # Temporarily move nginx.conf (otherwise dpkg fails)
 | 
			
		||||
    mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bkp \
 | 
			
		||||
    # Install add-on dependencies
 | 
			
		||||
    && apt-get update \
 | 
			
		||||
    && apt-get install -y --no-install-recommends \
 | 
			
		||||
        # Python for esphomeyaml
 | 
			
		||||
        python \
 | 
			
		||||
        python-pip \
 | 
			
		||||
        python-setuptools \
 | 
			
		||||
        # Python Pillow for display component
 | 
			
		||||
        python-pil \
 | 
			
		||||
        # Git for esphomelib downloads
 | 
			
		||||
        git \
 | 
			
		||||
    && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* && \
 | 
			
		||||
    pip install --no-cache-dir --no-binary :all: platformio && \
 | 
			
		||||
    platformio settings set enable_telemetry No && \
 | 
			
		||||
    platformio settings set check_libraries_interval 1000000 && \
 | 
			
		||||
    platformio settings set check_platformio_interval 1000000 && \
 | 
			
		||||
    platformio settings set check_platforms_interval 1000000
 | 
			
		||||
 | 
			
		||||
COPY docker/platformio.ini /pio/platformio.ini
 | 
			
		||||
RUN platformio run -d /pio; rm -rf /pio
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COPY . .
 | 
			
		||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
 | 
			
		||||
    pip install --no-cache-dir --no-binary :all: tzlocal
 | 
			
		||||
 | 
			
		||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
 | 
			
		||||
        # Ping for dashboard online/offline status
 | 
			
		||||
        iputils-ping \
 | 
			
		||||
        # NGINX proxy
 | 
			
		||||
        nginx \
 | 
			
		||||
    \
 | 
			
		||||
    && mv /etc/nginx/nginx.conf.bkp /etc/nginx/nginx.conf \
 | 
			
		||||
    \
 | 
			
		||||
    && pip2 install --no-cache-dir --no-binary :all: -e /opt/esphomeyaml \
 | 
			
		||||
    \
 | 
			
		||||
    # tzlocal for automatic timezone detection
 | 
			
		||||
    && pip2 install --no-cache-dir --no-binary :all: tzlocal \
 | 
			
		||||
    \
 | 
			
		||||
    # Change some platformio settings
 | 
			
		||||
    && platformio settings set enable_telemetry No \
 | 
			
		||||
    && platformio settings set check_libraries_interval 1000000 \
 | 
			
		||||
    && platformio settings set check_platformio_interval 1000000 \
 | 
			
		||||
    && platformio settings set check_platforms_interval 1000000 \
 | 
			
		||||
    \
 | 
			
		||||
    # Build an empty platformio project to force platformio to install all fw build dependencies
 | 
			
		||||
    # The return-code will be non-zero since there's nothing to build.
 | 
			
		||||
    && (platformio run -d /opt/pio; echo "Done") \
 | 
			
		||||
    \
 | 
			
		||||
    # Cleanup
 | 
			
		||||
    && rm -fr \
 | 
			
		||||
        /tmp/* \
 | 
			
		||||
        /var/{cache,log}/* \
 | 
			
		||||
        /var/lib/apt/lists/* \
 | 
			
		||||
        /opt/pio/
 | 
			
		||||
 | 
			
		||||
# Build arugments
 | 
			
		||||
ARG ADDON_ARCH
 | 
			
		||||
ARG ADDON_VERSION
 | 
			
		||||
ARG BUILD_ARCH=amd64
 | 
			
		||||
ARG BUILD_DATE
 | 
			
		||||
ARG BUILD_REF
 | 
			
		||||
ARG BUILD_VERSION
 | 
			
		||||
 | 
			
		||||
# Labels
 | 
			
		||||
LABEL \
 | 
			
		||||
    io.hass.name="esphomeyaml" \
 | 
			
		||||
    io.hass.description="esphomeyaml HassIO add-on for intelligently managing all your ESP8266/ESP32 devices." \
 | 
			
		||||
    io.hass.arch="${ADDON_ARCH}" \
 | 
			
		||||
    io.hass.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \
 | 
			
		||||
    io.hass.arch="${BUILD_ARCH}" \
 | 
			
		||||
    io.hass.type="addon" \
 | 
			
		||||
    io.hass.version="${ADDON_VERSION}" \
 | 
			
		||||
    io.hass.url="https://esphomelib.com/esphomeyaml/index.html" \
 | 
			
		||||
    maintainer="Otto Winter <contact@otto-winter.com>"
 | 
			
		||||
    io.hass.version=${BUILD_VERSION} \
 | 
			
		||||
    maintainer="Otto Winter <contact@otto-winter.com>" \
 | 
			
		||||
    org.label-schema.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \
 | 
			
		||||
    org.label-schema.build-date=${BUILD_DATE} \
 | 
			
		||||
    org.label-schema.name="esphomeyaml" \
 | 
			
		||||
    org.label-schema.schema-version="1.0" \
 | 
			
		||||
    org.label-schema.url="https://esphomelib.com" \
 | 
			
		||||
    org.label-schema.usage="https://github.com/OttoWinter/esphomeyaml/tree/dev/esphomeyaml/README.md" \
 | 
			
		||||
    org.label-schema.vcs-ref=${BUILD_REF} \
 | 
			
		||||
    org.label-schema.vcs-url="https://github.com/OttoWinter/esphomeyaml" \
 | 
			
		||||
    org.label-schema.vendor="esphomelib"
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 | 
			
		||||
        git \
 | 
			
		||||
    && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*rm -rf /var/lib/apt/lists/* /tmp/* && \
 | 
			
		||||
    pip install --no-cache-dir --no-binary :all: platformio && \
 | 
			
		||||
    platformio settings set enable_telemetry No
 | 
			
		||||
    platformio settings set enable_telemetry No && \
 | 
			
		||||
    platformio settings set check_libraries_interval 1000000 && \
 | 
			
		||||
    platformio settings set check_platformio_interval 1000000 && \
 | 
			
		||||
    platformio settings set check_platforms_interval 1000000
 | 
			
		||||
 | 
			
		||||
COPY docker/platformio.ini /pio/platformio.ini
 | 
			
		||||
RUN platformio run -d /pio; rm -rf /pio
 | 
			
		||||
@@ -16,4 +19,4 @@ RUN platformio run -d /pio; rm -rf /pio
 | 
			
		||||
COPY requirements.txt /requirements.txt
 | 
			
		||||
 | 
			
		||||
RUN pip install --no-cache-dir -r /requirements.txt && \
 | 
			
		||||
    pip install --no-cache-dir tzlocal pillow
 | 
			
		||||
    pip install --no-cache-dir tzlocal
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
  "name": "esphomeyaml-beta",
 | 
			
		||||
  "version": "1.9.3",
 | 
			
		||||
  "slug": "esphomeyaml-beta",
 | 
			
		||||
  "description": "Beta version of esphomeyaml HassIO add-on.",
 | 
			
		||||
  "description": "Beta version of esphomeyaml Hass.io add-on.",
 | 
			
		||||
  "url": "https://beta.esphomelib.com/esphomeyaml/index.html",
 | 
			
		||||
  "startup": "application",
 | 
			
		||||
  "webui": "http://[HOST]:[PORT:6052]",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,76 @@
 | 
			
		||||
# Dockerfile for HassIO edge add-on
 | 
			
		||||
ARG BUILD_FROM=homeassistant/amd64-base-ubuntu:latest
 | 
			
		||||
ARG BUILD_FROM=hassioaddons/ubuntu-base:2.2.0
 | 
			
		||||
# hadolint ignore=DL3006
 | 
			
		||||
FROM ${BUILD_FROM}
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get install -y --no-install-recommends \
 | 
			
		||||
# Set shell
 | 
			
		||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
 | 
			
		||||
 | 
			
		||||
# Copy root filesystem
 | 
			
		||||
COPY rootfs /
 | 
			
		||||
 | 
			
		||||
RUN \
 | 
			
		||||
    # Temporarily move nginx.conf (otherwise dpkg fails)
 | 
			
		||||
    mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bkp \
 | 
			
		||||
    # Install add-on dependencies
 | 
			
		||||
    && apt-get update \
 | 
			
		||||
    && apt-get install -y --no-install-recommends \
 | 
			
		||||
        # Python for esphomeyaml
 | 
			
		||||
        python \
 | 
			
		||||
        python-pip \
 | 
			
		||||
        python-setuptools \
 | 
			
		||||
        # Python Pillow for display component
 | 
			
		||||
        python-pil \
 | 
			
		||||
        # Git for esphomelib downloads
 | 
			
		||||
        git \
 | 
			
		||||
    && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* && \
 | 
			
		||||
    pip install --no-cache-dir --no-binary :all: platformio && \
 | 
			
		||||
    platformio settings set enable_telemetry No && \
 | 
			
		||||
    platformio settings set check_libraries_interval 1000000 && \
 | 
			
		||||
    platformio settings set check_platformio_interval 1000000 && \
 | 
			
		||||
    platformio settings set check_platforms_interval 1000000
 | 
			
		||||
        # Ping for dashboard online/offline status
 | 
			
		||||
        iputils-ping \
 | 
			
		||||
        # NGINX proxy
 | 
			
		||||
        nginx \
 | 
			
		||||
    \
 | 
			
		||||
    && mv /etc/nginx/nginx.conf.bkp /etc/nginx/nginx.conf \
 | 
			
		||||
    \
 | 
			
		||||
    && pip2 install --no-cache-dir --no-binary :all: https://github.com/OttoWinter/esphomeyaml/archive/dev.zip \
 | 
			
		||||
    \
 | 
			
		||||
    # tzlocal for automatic timezone detection
 | 
			
		||||
    && pip2 install --no-cache-dir --no-binary :all: tzlocal \
 | 
			
		||||
    \
 | 
			
		||||
    # Change some platformio settings
 | 
			
		||||
    && platformio settings set enable_telemetry No \
 | 
			
		||||
    && platformio settings set check_libraries_interval 1000000 \
 | 
			
		||||
    && platformio settings set check_platformio_interval 1000000 \
 | 
			
		||||
    && platformio settings set check_platforms_interval 1000000 \
 | 
			
		||||
    \
 | 
			
		||||
    # Build an empty platformio project to force platformio to install all fw build dependencies
 | 
			
		||||
    # The return-code will be non-zero since there's nothing to build.
 | 
			
		||||
    && (platformio run -d /opt/pio; echo "Done") \
 | 
			
		||||
    \
 | 
			
		||||
    # Cleanup
 | 
			
		||||
    && rm -fr \
 | 
			
		||||
        /tmp/* \
 | 
			
		||||
        /var/{cache,log}/* \
 | 
			
		||||
        /var/lib/apt/lists/* \
 | 
			
		||||
        /opt/pio/
 | 
			
		||||
 | 
			
		||||
COPY platformio.ini /pio/platformio.ini
 | 
			
		||||
RUN platformio run -d /pio; rm -rf /pio
 | 
			
		||||
# Build arugments
 | 
			
		||||
ARG BUILD_ARCH=amd64
 | 
			
		||||
ARG BUILD_DATE
 | 
			
		||||
ARG BUILD_REF
 | 
			
		||||
ARG BUILD_VERSION
 | 
			
		||||
 | 
			
		||||
RUN pip install --no-cache-dir git+https://github.com/OttoWinter/esphomeyaml.git@dev#egg=esphomeyaml && \
 | 
			
		||||
    pip install --no-cache-dir pillow tzlocal
 | 
			
		||||
 | 
			
		||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
 | 
			
		||||
# Labels
 | 
			
		||||
LABEL \
 | 
			
		||||
    io.hass.name="esphomeyaml-edge" \
 | 
			
		||||
    io.hass.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \
 | 
			
		||||
    io.hass.arch="${BUILD_ARCH}" \
 | 
			
		||||
    io.hass.type="addon" \
 | 
			
		||||
    io.hass.version=${BUILD_VERSION} \
 | 
			
		||||
    maintainer="Otto Winter <contact@otto-winter.com>" \
 | 
			
		||||
    org.label-schema.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \
 | 
			
		||||
    org.label-schema.build-date=${BUILD_DATE} \
 | 
			
		||||
    org.label-schema.name="esphomeyaml-edge" \
 | 
			
		||||
    org.label-schema.schema-version="1.0" \
 | 
			
		||||
    org.label-schema.url="https://esphomelib.com" \
 | 
			
		||||
    org.label-schema.usage="https://github.com/OttoWinter/esphomeyaml/tree/dev/esphomeyaml-edge/README.md" \
 | 
			
		||||
    org.label-schema.vcs-ref=${BUILD_REF} \
 | 
			
		||||
    org.label-schema.vcs-url="https://github.com/OttoWinter/esphomeyaml" \
 | 
			
		||||
    org.label-schema.vendor="esphomelib"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										123
									
								
								esphomeyaml-edge/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								esphomeyaml-edge/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
# Esphomeyaml Hass.io Add-On
 | 
			
		||||
 | 
			
		||||
[![GitHub Release][releases-shield]][releases]
 | 
			
		||||
![Project Stage][project-stage-shield]
 | 
			
		||||
[![License][license-shield]](LICENSE.md)
 | 
			
		||||
 | 
			
		||||
[![GitLab CI][gitlabci-shield]][gitlabci]
 | 
			
		||||
![Project Maintenance][maintenance-shield]
 | 
			
		||||
[![GitHub Activity][commits-shield]][commits]
 | 
			
		||||
 | 
			
		||||
[![Discord][discord-shield]][discord]
 | 
			
		||||
[![Community Forum][forum-shield]][forum]
 | 
			
		||||
 | 
			
		||||
[](https://esphomelib.com/esphomeyaml/index.html)
 | 
			
		||||
 | 
			
		||||
## About
 | 
			
		||||
 | 
			
		||||
This add-on allows you to manage and program your ESP8266 and ESP32 based microcontrollers
 | 
			
		||||
directly through Hass.io **with no programming experience required**. All you need to do
 | 
			
		||||
is write YAML configuration files; the rest (over-the-air updates, compiling) is all
 | 
			
		||||
handled by esphomeyaml.
 | 
			
		||||
 | 
			
		||||
<p align="center">
 | 
			
		||||
<img title="esphomeyaml dashboard screenshot" src="images/screenshot.png" width="700px"></img>
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
[_View the esphomeyaml documentation here_](https://esphomelib.com/esphomeyaml/index.html)
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
With esphomeyaml, you can go from a few lines of YAML straight to a custom-made
 | 
			
		||||
firmware. For example, to include a [DHT22][dht22].
 | 
			
		||||
temperature and humidity sensor, you just need to include 8 lines of YAML
 | 
			
		||||
in your configuration file:
 | 
			
		||||
 | 
			
		||||
<img title="esphomeyaml DHT configuration example" src="images/dht-example.png" width="500px"></img>
 | 
			
		||||
 | 
			
		||||
Then just click UPLOAD and the sensor will magically appear in Home Assistant:
 | 
			
		||||
 | 
			
		||||
<img title="esphomelib Home Assistant MQTT discovery" src="images/temperature-humidity.png" width="600px"></img>
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
To install this Hass.io add-on you need to add the esphomeyaml add-on repository
 | 
			
		||||
first:
 | 
			
		||||
 | 
			
		||||
1. Add our Hass.io add-ons repository to your Hass.io instance. You can do this by navigating to the "Add-on Store" tab in the Hass.io panel and then entering https://github.com/hassio-addons/repository in the "Add new repository by URL" field.
 | 
			
		||||
2. Now scroll down and select the "esphomeyaml" add-on.
 | 
			
		||||
3. Press install to download the add-on and unpack it on your machine. This can take some time.
 | 
			
		||||
4. Optional: If you're using SSL certificates and want to encrypt your communication to this add-on, please enter `true` into the `ssl` field and set the `fullchain` and `certfile` options accordingly.
 | 
			
		||||
5. Start the add-on, check the logs of the add-on to see if everything went well.
 | 
			
		||||
6. Click "OPEN WEB UI" to open the esphomeyaml dashboard. You will be asked for your Home Assistant credentials - esphomeyaml uses Hass.io's authentication system to log you in.
 | 
			
		||||
 | 
			
		||||
**NOTE**: Installation on RPis running in 64-bit mode is currently not possible. Please use the 32-bit variant of HassOS instead.
 | 
			
		||||
 | 
			
		||||
You can view the esphomeyaml docs here: https://esphomelib.com/esphomeyaml/index.html
 | 
			
		||||
 | 
			
		||||
## Configuration
 | 
			
		||||
 | 
			
		||||
**Note**: _Remember to restart the add-on when the configuration is changed._
 | 
			
		||||
 | 
			
		||||
Example add-on configuration:
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
  "ssl": true,
 | 
			
		||||
  "certfile": "fullchain.pem",
 | 
			
		||||
  "keyfile": "privkey.pem"
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Option: `ssl`
 | 
			
		||||
 | 
			
		||||
Enables/Disables encrypted SSL (HTTPS) connections to the web server of this add-on. Set it to `true` to encrypt communications, `false` otherwise. Please note that if you set this to `true` you must also specify a `certfile` and `keyfile`.
 | 
			
		||||
 | 
			
		||||
### Option: `certfile`
 | 
			
		||||
 | 
			
		||||
The certificate file to use for SSL.
 | 
			
		||||
 | 
			
		||||
**Note**: _The file MUST be stored in `/ssl/`, which is the default for Hass.io_
 | 
			
		||||
 | 
			
		||||
### Option: `keyfile`
 | 
			
		||||
 | 
			
		||||
The private key file to use for SSL.
 | 
			
		||||
 | 
			
		||||
**Note**: _The file MUST be stored in `/ssl/`, which is the default for Hass.io_
 | 
			
		||||
 | 
			
		||||
### Option: `leave_front_door_open`
 | 
			
		||||
 | 
			
		||||
Adding this option to the add-on configuration allows you to disable
 | 
			
		||||
authentication by setting it to `true`.
 | 
			
		||||
 | 
			
		||||
## Embedding into Home Assistant
 | 
			
		||||
 | 
			
		||||
It is possible to embed the esphomeyaml dashboard directly into
 | 
			
		||||
Home Assistant, allowing you to access your ESP nodes through
 | 
			
		||||
the Home Assistant frontend using the `panel_iframe` component.
 | 
			
		||||
 | 
			
		||||
Example configuration:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
panel_iframe:
 | 
			
		||||
  esphomeyaml:
 | 
			
		||||
    title: esphomeyaml Dashboard
 | 
			
		||||
    icon: mdi:code-brackets
 | 
			
		||||
    url: https://addres.to.your.hass.io:6052
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[commits-shield]: https://img.shields.io/github/commit-activity/y/hassio-addons/addon-esphomeyaml.svg
 | 
			
		||||
[commits]: https://github.com/hassio-addons/addon-esphomeyaml/commits/master
 | 
			
		||||
[discord-shield]: https://img.shields.io/discord/429907082951524364.svg
 | 
			
		||||
[dht22]: https://esphomelib.com/esphomeyaml/components/sensor/dht.html
 | 
			
		||||
[discord]: https://discord.me/KhAMKrd
 | 
			
		||||
[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg
 | 
			
		||||
[forum]: https://community.home-assistant.io/c/third-party/esphomelib
 | 
			
		||||
[gitlabci-shield]: https://gitlab.com/hassio-addons/addon-esphomeyaml/badges/master/pipeline.svg
 | 
			
		||||
[gitlabci]: https://gitlab.com/hassio-addons/addon-esphomeyaml/pipelines
 | 
			
		||||
[license-shield]: https://img.shields.io/github/license/hassio-addons/addon-esphomeyaml.svg
 | 
			
		||||
[maintenance-shield]: https://img.shields.io/maintenance/yes/2018.svg
 | 
			
		||||
[project-stage-shield]: https://img.shields.io/badge/project%20stage-stable-green.svg
 | 
			
		||||
[releases-shield]: https://img.shields.io/github/release/hassio-addons/addon-esphomeyaml.svg
 | 
			
		||||
[releases]: https://github.com/hassio-addons/addon-esphomeyaml/releases
 | 
			
		||||
[repository]: https://github.com/hassio-addons/repository
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
    "squash": false,
 | 
			
		||||
    "build_from": {
 | 
			
		||||
        "aarch64": "homeassistant/aarch64-base-ubuntu:latest",
 | 
			
		||||
        "amd64": "homeassistant/amd64-base-ubuntu:latest",
 | 
			
		||||
        "armhf": "homeassistant/armhf-base-ubuntu:latest",
 | 
			
		||||
        "i386": "homeassistant/i386-base-ubuntu:latest"
 | 
			
		||||
    },
 | 
			
		||||
    "args": {}
 | 
			
		||||
  "squash": false,
 | 
			
		||||
  "build_from": {
 | 
			
		||||
    "aarch64": "hassioaddons/ubuntu-base-aarch64:2.2.0",
 | 
			
		||||
    "amd64": "hassioaddons/ubuntu-base-amd64:2.2.0",
 | 
			
		||||
    "armhf": "hassioaddons/ubuntu-base-armhf:2.2.0",
 | 
			
		||||
    "i386": "hassioaddons/ubuntu-base-i386:2.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "args": {}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,32 +2,41 @@
 | 
			
		||||
  "name": "esphomeyaml-edge",
 | 
			
		||||
  "version": "dev",
 | 
			
		||||
  "slug": "esphomeyaml-edge",
 | 
			
		||||
  "description": "Development build of the esphomeyaml HassIO add-on.",
 | 
			
		||||
  "url": "https://esphomelib.com/esphomeyaml/index.html",
 | 
			
		||||
  "startup": "application",
 | 
			
		||||
  "description": "Development Version! Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files",
 | 
			
		||||
  "url": "https://github.com/OttoWinter/esphomeyaml/tree/dev/esphomeyaml-edge/README.md",
 | 
			
		||||
  "webui": "http://[HOST]:[PORT:6052]",
 | 
			
		||||
  "boot": "auto",
 | 
			
		||||
  "ports": {
 | 
			
		||||
    "6052/tcp": 6052,
 | 
			
		||||
    "6053/tcp": 6053
 | 
			
		||||
  },
 | 
			
		||||
  "startup": "application",
 | 
			
		||||
  "arch": [
 | 
			
		||||
    "aarch64",
 | 
			
		||||
    "amd64",
 | 
			
		||||
    "armhf",
 | 
			
		||||
    "i386"
 | 
			
		||||
  ],
 | 
			
		||||
  "auto_uart": true,
 | 
			
		||||
  "hassio_api": true,
 | 
			
		||||
  "auth_api": true,
 | 
			
		||||
  "services": [
 | 
			
		||||
    "mqtt:want"
 | 
			
		||||
  ],
 | 
			
		||||
  "hassio_role": "default",
 | 
			
		||||
  "homeassistant_api": false,
 | 
			
		||||
  "host_network": false,
 | 
			
		||||
  "boot": "auto",
 | 
			
		||||
  "ports": {
 | 
			
		||||
    "6052/tcp": 6052
 | 
			
		||||
  },
 | 
			
		||||
  "map": [
 | 
			
		||||
    "ssl",
 | 
			
		||||
    "config:rw"
 | 
			
		||||
  ],
 | 
			
		||||
  "options": {
 | 
			
		||||
    "password": ""
 | 
			
		||||
    "ssl": false,
 | 
			
		||||
    "certfile": "fullchain.pem",
 | 
			
		||||
    "keyfile": "privkey.pem"
 | 
			
		||||
  },
 | 
			
		||||
  "schema": {
 | 
			
		||||
    "password": "str?"
 | 
			
		||||
  },
 | 
			
		||||
  "environment": {
 | 
			
		||||
    "ESPHOMEYAML_OTA_HOST_PORT": "6053"
 | 
			
		||||
    "ssl": "bool",
 | 
			
		||||
    "certfile": "str",
 | 
			
		||||
    "keyfile": "str",
 | 
			
		||||
    "leave_front_door_open": "bool?"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								esphomeyaml-edge/images/dht-example.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								esphomeyaml-edge/images/dht-example.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 17 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								esphomeyaml-edge/images/screenshot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								esphomeyaml-edge/images/screenshot.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 50 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								esphomeyaml-edge/images/temperature-humidity.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								esphomeyaml-edge/images/temperature-humidity.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.3 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 8.6 KiB  | 
							
								
								
									
										35
									
								
								esphomeyaml-edge/rootfs/etc/cont-init.d/10-requirements.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										35
									
								
								esphomeyaml-edge/rootfs/etc/cont-init.d/10-requirements.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: esphomeyaml
 | 
			
		||||
# 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.'
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! hass.config.has_value 'keyfile'; then
 | 
			
		||||
        hass.die 'SSL is enabled, but no keyfile was specified'
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! hass.file_exists "/ssl/$(hass.config.get 'certfile')"; then
 | 
			
		||||
        if ! hass.file_exists "/ssl/$(hass.config.get '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 esphomeyaml dashboard, you can manually disable
 | 
			
		||||
            SSL by setting \"ssl\" to false."
 | 
			
		||||
            hass.die "${text}"
 | 
			
		||||
        fi
 | 
			
		||||
        hass.die 'The configured certfile is not found'
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! hass.file_exists "/ssl/$(hass.config.get 'keyfile')"; then
 | 
			
		||||
        hass.die 'The configured keyfile is not found'
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
							
								
								
									
										24
									
								
								esphomeyaml-edge/rootfs/etc/cont-init.d/20-nginx.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								esphomeyaml-edge/rootfs/etc/cont-init.d/20-nginx.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: esphomeyaml
 | 
			
		||||
# Configures NGINX for use with esphomeyaml
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
declare certfile
 | 
			
		||||
declare keyfile
 | 
			
		||||
 | 
			
		||||
mkdir -p /var/log/nginx
 | 
			
		||||
 | 
			
		||||
# Enable SSL
 | 
			
		||||
if hass.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')
 | 
			
		||||
 | 
			
		||||
    sed -i "s/%%certfile%%/${certfile}/g" /etc/nginx/nginx.conf
 | 
			
		||||
    sed -i "s/%%keyfile%%/${keyfile}/g" /etc/nginx/nginx.conf
 | 
			
		||||
fi
 | 
			
		||||
							
								
								
									
										62
									
								
								esphomeyaml-edge/rootfs/etc/nginx/nginx-ssl.conf
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										62
									
								
								esphomeyaml-edge/rootfs/etc/nginx/nginx-ssl.conf
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
worker_processes  1;
 | 
			
		||||
pid /var/run/nginx.pid;
 | 
			
		||||
error_log stderr;
 | 
			
		||||
 | 
			
		||||
events {
 | 
			
		||||
    worker_connections  1024;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
http {
 | 
			
		||||
    access_log         stdout;
 | 
			
		||||
    include            mime.types;
 | 
			
		||||
    default_type       application/octet-stream;
 | 
			
		||||
    sendfile           on;
 | 
			
		||||
    keepalive_timeout  65;
 | 
			
		||||
 | 
			
		||||
    upstream esphomeyaml {
 | 
			
		||||
        ip_hash;
 | 
			
		||||
        server 127.0.0.1:80;
 | 
			
		||||
    }
 | 
			
		||||
    map $http_upgrade $connection_upgrade {
 | 
			
		||||
        default upgrade;
 | 
			
		||||
        ''      close;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server {
 | 
			
		||||
        server_name hassio.local;
 | 
			
		||||
        listen 6052 default_server ssl;
 | 
			
		||||
        root /dev/null;
 | 
			
		||||
 | 
			
		||||
        ssl_certificate /ssl/%%certfile%%;
 | 
			
		||||
        ssl_certificate_key /ssl/%%keyfile%%;
 | 
			
		||||
        ssl_protocols TLSv1.2;
 | 
			
		||||
        ssl_prefer_server_ciphers on;
 | 
			
		||||
        ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA;
 | 
			
		||||
        ssl_ecdh_curve secp384r1;
 | 
			
		||||
        ssl_session_timeout  10m;
 | 
			
		||||
        ssl_session_cache shared:SSL:10m;
 | 
			
		||||
        ssl_session_tickets off;
 | 
			
		||||
        ssl_stapling on;
 | 
			
		||||
        ssl_stapling_verify on;
 | 
			
		||||
 | 
			
		||||
        # Redirect http requests to https on the same port.
 | 
			
		||||
        # https://rageagainstshell.com/2016/11/redirect-http-to-https-on-the-same-port-in-nginx/
 | 
			
		||||
        error_page 497 https://$http_host$request_uri;
 | 
			
		||||
 | 
			
		||||
        location / {
 | 
			
		||||
            proxy_redirect off;
 | 
			
		||||
            proxy_pass http://esphomeyaml;
 | 
			
		||||
 | 
			
		||||
            proxy_http_version 1.1;
 | 
			
		||||
            proxy_set_header Upgrade $http_upgrade;
 | 
			
		||||
            proxy_set_header Connection $connection_upgrade;
 | 
			
		||||
            proxy_set_header Authorization "";
 | 
			
		||||
 | 
			
		||||
            proxy_set_header X-Real-IP $remote_addr;
 | 
			
		||||
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 | 
			
		||||
            proxy_set_header X-Forwarded-Proto $scheme;
 | 
			
		||||
            proxy_set_header Host $http_host;
 | 
			
		||||
            proxy_set_header X-NginX-Proxy true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								esphomeyaml-edge/rootfs/etc/nginx/nginx.conf
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								esphomeyaml-edge/rootfs/etc/nginx/nginx.conf
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
worker_processes  1;
 | 
			
		||||
pid /var/run/nginx.pid;
 | 
			
		||||
error_log stderr;
 | 
			
		||||
 | 
			
		||||
events {
 | 
			
		||||
    worker_connections  1024;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
http {
 | 
			
		||||
    access_log         stdout;
 | 
			
		||||
    include            mime.types;
 | 
			
		||||
    default_type       application/octet-stream;
 | 
			
		||||
    sendfile           on;
 | 
			
		||||
    keepalive_timeout  65;
 | 
			
		||||
 | 
			
		||||
    upstream esphomeyaml {
 | 
			
		||||
        ip_hash;
 | 
			
		||||
        server 127.0.0.1:80;
 | 
			
		||||
    }
 | 
			
		||||
    map $http_upgrade $connection_upgrade {
 | 
			
		||||
        default upgrade;
 | 
			
		||||
        ''      close;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server {
 | 
			
		||||
        server_name hassio.local;
 | 
			
		||||
        listen 6052 default_server;
 | 
			
		||||
        root /dev/null;
 | 
			
		||||
 | 
			
		||||
        location / {
 | 
			
		||||
            proxy_redirect off;
 | 
			
		||||
            proxy_pass http://esphomeyaml;
 | 
			
		||||
 | 
			
		||||
            proxy_http_version 1.1;
 | 
			
		||||
            proxy_set_header Upgrade $http_upgrade;
 | 
			
		||||
            proxy_set_header Connection $connection_upgrade;
 | 
			
		||||
            proxy_set_header Authorization "";
 | 
			
		||||
 | 
			
		||||
            proxy_set_header X-Real-IP $remote_addr;
 | 
			
		||||
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 | 
			
		||||
            proxy_set_header X-Forwarded-Proto $scheme;
 | 
			
		||||
            proxy_set_header Host $http_host;
 | 
			
		||||
            proxy_set_header X-NginX-Proxy true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/finish
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/finish
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#!/usr/bin/execlineb -S0
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: esphomeyaml
 | 
			
		||||
# Take down the S6 supervision tree when esphomeyaml fails
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
if -n { s6-test $# -ne 0 }
 | 
			
		||||
if -n { s6-test ${1} -eq 256 }
 | 
			
		||||
 | 
			
		||||
s6-svscanctl -t /var/run/s6/services
 | 
			
		||||
							
								
								
									
										14
									
								
								esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								esphomeyaml-edge/rootfs/etc/services.d/esphomeyaml/run
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: esphomeyaml
 | 
			
		||||
# Runs the esphomeyaml dashboard
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
if hass.config.true 'leave_front_door_open'; then
 | 
			
		||||
    export DISABLE_HA_AUTHENTICATION=true
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
hass.log.info "Starting esphomeyaml dashboard..."
 | 
			
		||||
exec esphomeyaml /config/esphomeyaml dashboard --port 80 --hassio
 | 
			
		||||
							
								
								
									
										9
									
								
								esphomeyaml-edge/rootfs/etc/services.d/nginx/finish
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								esphomeyaml-edge/rootfs/etc/services.d/nginx/finish
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#!/usr/bin/execlineb -S0
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: esphomeyaml
 | 
			
		||||
# Take down the S6 supervision tree when NGINX fails
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
if -n { s6-test $# -ne 0 }
 | 
			
		||||
if -n { s6-test ${1} -eq 256 }
 | 
			
		||||
 | 
			
		||||
s6-svscanctl -t /var/run/s6/services
 | 
			
		||||
							
								
								
									
										10
									
								
								esphomeyaml-edge/rootfs/etc/services.d/nginx/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								esphomeyaml-edge/rootfs/etc/services.d/nginx/run
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
#!/usr/bin/with-contenv bash
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# Community Hass.io Add-ons: esphomeyaml
 | 
			
		||||
# Runs the NGINX proxy
 | 
			
		||||
# ==============================================================================
 | 
			
		||||
# shellcheck disable=SC1091
 | 
			
		||||
source /usr/lib/hassio-addons/base.sh
 | 
			
		||||
 | 
			
		||||
hass.log.info "Starting NGINX..."
 | 
			
		||||
exec nginx -g "daemon off;"
 | 
			
		||||
							
								
								
									
										12
									
								
								esphomeyaml-edge/rootfs/opt/pio/platformio.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								esphomeyaml-edge/rootfs/opt/pio/platformio.ini
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
; This file allows the docker build file to install the required platformio
 | 
			
		||||
; platforms
 | 
			
		||||
 | 
			
		||||
[env:espressif8266]
 | 
			
		||||
platform = espressif8266
 | 
			
		||||
board = nodemcuv2
 | 
			
		||||
framework = arduino
 | 
			
		||||
 | 
			
		||||
[env:espressif32]
 | 
			
		||||
platform = espressif32
 | 
			
		||||
board = nodemcu-32s
 | 
			
		||||
framework = arduino
 | 
			
		||||
@@ -2,21 +2,23 @@ from __future__ import print_function
 | 
			
		||||
 | 
			
		||||
import argparse
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
import random
 | 
			
		||||
import sys
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import const, core, core_config, mqtt, wizard, writer, yaml_util, platformio_api
 | 
			
		||||
from esphomeyaml.config import get_component, iter_components, read_config
 | 
			
		||||
from esphomeyaml.const import CONF_BAUD_RATE, CONF_BUILD_PATH, CONF_DOMAIN, CONF_ESPHOMEYAML, \
 | 
			
		||||
from esphomeyaml import const, core_config, mqtt, platformio_api, wizard, writer, yaml_util
 | 
			
		||||
from esphomeyaml.config import get_component, iter_components, read_config, strip_default_ids
 | 
			
		||||
from esphomeyaml.const import CONF_BAUD_RATE, CONF_DOMAIN, CONF_ESPHOMEYAML, \
 | 
			
		||||
    CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_USE_CUSTOM_CODE, \
 | 
			
		||||
    CONF_WIFI, ESP_PLATFORM_ESP8266
 | 
			
		||||
from esphomeyaml.core import ESPHomeYAMLError
 | 
			
		||||
from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, \
 | 
			
		||||
    _EXPRESSIONS, add, add_job, color, flush_tasks, indent, statement, relative_path
 | 
			
		||||
from esphomeyaml.util import safe_print, run_external_command
 | 
			
		||||
    CONF_WIFI
 | 
			
		||||
from esphomeyaml.core import CORE, EsphomeyamlError
 | 
			
		||||
from esphomeyaml.cpp_generator import Expression, RawStatement, add, statement
 | 
			
		||||
from esphomeyaml.helpers import color, indent
 | 
			
		||||
from esphomeyaml.storage_json import StorageJSON, storage_path, start_update_check_thread, \
 | 
			
		||||
    esphomeyaml_storage_path
 | 
			
		||||
from esphomeyaml.util import run_external_command, safe_print
 | 
			
		||||
 | 
			
		||||
_LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
@@ -32,6 +34,7 @@ def get_serial_ports():
 | 
			
		||||
            continue
 | 
			
		||||
        if "VID:PID" in info:
 | 
			
		||||
            result.append((port, desc))
 | 
			
		||||
    result.sort(key=lambda x: x[0])
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +65,7 @@ def choose_serial_port(config):
 | 
			
		||||
    return result[opt][0]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run_miniterm(config, port, escape=False):
 | 
			
		||||
def run_miniterm(config, port):
 | 
			
		||||
    import serial
 | 
			
		||||
    if CONF_LOGGER not in config:
 | 
			
		||||
        _LOGGER.info("Logger is not enabled. Not starting UART logs.")
 | 
			
		||||
@@ -83,8 +86,6 @@ def run_miniterm(config, port, escape=False):
 | 
			
		||||
            line = raw.replace('\r', '').replace('\n', '')
 | 
			
		||||
            time = datetime.now().time().strftime('[%H:%M:%S]')
 | 
			
		||||
            message = time + line
 | 
			
		||||
            if escape:
 | 
			
		||||
                message = message.replace('\033', '\\033')
 | 
			
		||||
            safe_print(message)
 | 
			
		||||
 | 
			
		||||
            backtrace_state = platformio_api.process_stacktrace(
 | 
			
		||||
@@ -94,43 +95,40 @@ def run_miniterm(config, port, escape=False):
 | 
			
		||||
def write_cpp(config):
 | 
			
		||||
    _LOGGER.info("Generating C++ source...")
 | 
			
		||||
 | 
			
		||||
    add_job(core_config.to_code, config[CONF_ESPHOMEYAML], domain='esphomeyaml')
 | 
			
		||||
    CORE.add_job(core_config.to_code, config[CONF_ESPHOMEYAML], domain='esphomeyaml')
 | 
			
		||||
    for domain in PRE_INITIALIZE:
 | 
			
		||||
        if domain == CONF_ESPHOMEYAML or domain not in config:
 | 
			
		||||
            continue
 | 
			
		||||
        add_job(get_component(domain).to_code, config[domain], domain=domain)
 | 
			
		||||
        CORE.add_job(get_component(domain).to_code, config[domain], domain=domain)
 | 
			
		||||
 | 
			
		||||
    for domain, component, conf in iter_components(config):
 | 
			
		||||
        if domain in PRE_INITIALIZE or not hasattr(component, 'to_code'):
 | 
			
		||||
            continue
 | 
			
		||||
        add_job(component.to_code, conf, domain=domain)
 | 
			
		||||
        CORE.add_job(component.to_code, conf, domain=domain)
 | 
			
		||||
 | 
			
		||||
    flush_tasks()
 | 
			
		||||
    CORE.flush_tasks()
 | 
			
		||||
    add(RawStatement(''))
 | 
			
		||||
    add(RawStatement(''))
 | 
			
		||||
    all_code = []
 | 
			
		||||
    for exp in _EXPRESSIONS:
 | 
			
		||||
    for exp in CORE.expressions:
 | 
			
		||||
        if not config[CONF_ESPHOMEYAML][CONF_USE_CUSTOM_CODE]:
 | 
			
		||||
            if isinstance(exp, Expression) and not exp.required:
 | 
			
		||||
                continue
 | 
			
		||||
            if isinstance(exp, AssignmentExpression) and not exp.obj.required:
 | 
			
		||||
                if not exp.has_side_effects():
 | 
			
		||||
                    continue
 | 
			
		||||
                exp = exp.rhs
 | 
			
		||||
        all_code.append(unicode(statement(exp)))
 | 
			
		||||
 | 
			
		||||
    build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
 | 
			
		||||
    writer.write_platformio_project(config, build_path)
 | 
			
		||||
    writer.write_platformio_project()
 | 
			
		||||
 | 
			
		||||
    code_s = indent('\n'.join(line.rstrip() for line in all_code))
 | 
			
		||||
    cpp_path = os.path.join(build_path, 'src', 'main.cpp')
 | 
			
		||||
    writer.write_cpp(code_s, cpp_path)
 | 
			
		||||
    writer.write_cpp(code_s)
 | 
			
		||||
    return 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def compile_program(args, config):
 | 
			
		||||
    _LOGGER.info("Compiling app...")
 | 
			
		||||
    return platformio_api.run_compile(config, args.verbose)
 | 
			
		||||
    thread = start_update_check_thread(esphomeyaml_storage_path(CORE.config_dir))
 | 
			
		||||
    rc = platformio_api.run_compile(config, args.verbose)
 | 
			
		||||
    thread.join()
 | 
			
		||||
    return rc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_upload_host(config):
 | 
			
		||||
@@ -146,8 +144,7 @@ def get_upload_host(config):
 | 
			
		||||
def upload_using_esptool(config, port):
 | 
			
		||||
    import esptool
 | 
			
		||||
 | 
			
		||||
    build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
 | 
			
		||||
    path = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
 | 
			
		||||
    path = os.path.join(CORE.build_path, '.pioenvs', CORE.name, 'firmware.bin')
 | 
			
		||||
    cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
 | 
			
		||||
           '--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path]
 | 
			
		||||
    # pylint: disable=protected-access
 | 
			
		||||
@@ -155,12 +152,10 @@ def upload_using_esptool(config, port):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def upload_program(config, args, port):
 | 
			
		||||
    build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
 | 
			
		||||
 | 
			
		||||
    # if upload is to a serial port use platformio, otherwise assume ota
 | 
			
		||||
    serial_port = port.startswith('/') or port.startswith('COM')
 | 
			
		||||
    if port != 'OTA' and serial_port:
 | 
			
		||||
        if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266 and args.use_esptoolpy:
 | 
			
		||||
        if CORE.is_esp8266:
 | 
			
		||||
            return upload_using_esptool(config, port)
 | 
			
		||||
        return platformio_api.run_upload(config, args.verbose, port)
 | 
			
		||||
 | 
			
		||||
@@ -178,7 +173,6 @@ def upload_program(config, args, port):
 | 
			
		||||
    from esphomeyaml.components import ota
 | 
			
		||||
    from esphomeyaml import espota2
 | 
			
		||||
 | 
			
		||||
    bin_file = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
 | 
			
		||||
    if args.host_port is not None:
 | 
			
		||||
        host_port = args.host_port
 | 
			
		||||
    else:
 | 
			
		||||
@@ -188,20 +182,27 @@ def upload_program(config, args, port):
 | 
			
		||||
    remote_port = ota.get_port(config)
 | 
			
		||||
    password = ota.get_auth(config)
 | 
			
		||||
 | 
			
		||||
    res = espota2.run_ota(host, remote_port, password, bin_file)
 | 
			
		||||
    storage = StorageJSON.load(storage_path())
 | 
			
		||||
    res = espota2.run_ota(host, remote_port, password, CORE.firmware_bin)
 | 
			
		||||
    if res == 0:
 | 
			
		||||
        if storage is not None and storage.use_legacy_ota:
 | 
			
		||||
            storage.use_legacy_ota = False
 | 
			
		||||
            storage.save(storage_path())
 | 
			
		||||
        return res
 | 
			
		||||
    if storage is not None and not storage.use_legacy_ota:
 | 
			
		||||
        return res
 | 
			
		||||
 | 
			
		||||
    _LOGGER.warn("OTA v2 method failed. Trying with legacy OTA...")
 | 
			
		||||
    return espota2.run_legacy_ota(verbose, host_port, host, remote_port, password, bin_file)
 | 
			
		||||
    return espota2.run_legacy_ota(verbose, host_port, host, remote_port, password,
 | 
			
		||||
                                  CORE.firmware_bin)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def show_logs(config, args, port, escape=False):
 | 
			
		||||
def show_logs(config, args, port):
 | 
			
		||||
    serial_port = port.startswith('/') or port.startswith('COM')
 | 
			
		||||
    if port != 'OTA' and serial_port:
 | 
			
		||||
        run_miniterm(config, port, escape=escape)
 | 
			
		||||
        run_miniterm(config, port)
 | 
			
		||||
        return 0
 | 
			
		||||
    return mqtt.show_logs(config, args.topic, args.username, args.password, args.client_id,
 | 
			
		||||
                          escape=escape)
 | 
			
		||||
    return mqtt.show_logs(config, args.topic, args.username, args.password, args.client_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def clean_mqtt(config, args):
 | 
			
		||||
@@ -239,26 +240,8 @@ def command_wizard(args):
 | 
			
		||||
    return wizard.wizard(args.configuration)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def strip_default_ids(config):
 | 
			
		||||
    value = config
 | 
			
		||||
    if isinstance(config, list):
 | 
			
		||||
        value = type(config)()
 | 
			
		||||
        for x in config:
 | 
			
		||||
            if isinstance(x, core.ID) and not x.is_manual:
 | 
			
		||||
                continue
 | 
			
		||||
            value.append(strip_default_ids(x))
 | 
			
		||||
        return value
 | 
			
		||||
    elif isinstance(config, dict):
 | 
			
		||||
        value = type(config)()
 | 
			
		||||
        for k, v in config.iteritems():
 | 
			
		||||
            if isinstance(v, core.ID) and not v.is_manual:
 | 
			
		||||
                continue
 | 
			
		||||
            value[k] = strip_default_ids(v)
 | 
			
		||||
        return value
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def command_config(args, config):
 | 
			
		||||
    _LOGGER.info("Configuration is valid!")
 | 
			
		||||
    if not args.verbose:
 | 
			
		||||
        config = strip_default_ids(config)
 | 
			
		||||
    safe_print(yaml_util.dump(config))
 | 
			
		||||
@@ -290,7 +273,7 @@ def command_upload(args, config):
 | 
			
		||||
 | 
			
		||||
def command_logs(args, config):
 | 
			
		||||
    port = args.serial_port or choose_serial_port(config)
 | 
			
		||||
    return show_logs(config, args, port, escape=args.escape)
 | 
			
		||||
    return show_logs(config, args, port)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def command_run(args, config):
 | 
			
		||||
@@ -308,7 +291,7 @@ def command_run(args, config):
 | 
			
		||||
    _LOGGER.info(u"Successfully uploaded program.")
 | 
			
		||||
    if args.no_logs:
 | 
			
		||||
        return 0
 | 
			
		||||
    return show_logs(config, args, port, escape=args.escape)
 | 
			
		||||
    return show_logs(config, args, port)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def command_clean_mqtt(args, config):
 | 
			
		||||
@@ -325,9 +308,8 @@ def command_version(args):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def command_clean(args, config):
 | 
			
		||||
    build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
 | 
			
		||||
    try:
 | 
			
		||||
        writer.clean_build(build_path)
 | 
			
		||||
        writer.clean_build()
 | 
			
		||||
    except OSError as err:
 | 
			
		||||
        _LOGGER.error("Error deleting build files: %s", err)
 | 
			
		||||
        return 1
 | 
			
		||||
@@ -403,9 +385,6 @@ def parse_args(argv):
 | 
			
		||||
    parser_upload.add_argument('--upload-port', help="Manually specify the upload port to use. "
 | 
			
		||||
                                                     "For example /dev/cu.SLAB_USBtoUART.")
 | 
			
		||||
    parser_upload.add_argument('--host-port', help="Specify the host port.", type=int)
 | 
			
		||||
    parser_upload.add_argument('--use-esptoolpy',
 | 
			
		||||
                               help="Use esptool.py for the uploading (only for ESP8266)",
 | 
			
		||||
                               action='store_true')
 | 
			
		||||
 | 
			
		||||
    parser_logs = subparsers.add_parser('logs', help='Validate the configuration '
 | 
			
		||||
                                                     'and show all MQTT logs.')
 | 
			
		||||
@@ -415,8 +394,6 @@ def parse_args(argv):
 | 
			
		||||
    parser_logs.add_argument('--client-id', help='Manually set the client id.')
 | 
			
		||||
    parser_logs.add_argument('--serial-port', help="Manually specify a serial port to use"
 | 
			
		||||
                                                   "For example /dev/cu.SLAB_USBtoUART.")
 | 
			
		||||
    parser_logs.add_argument('--escape', help="Escape ANSI color codes for running in dashboard",
 | 
			
		||||
                             action='store_true')
 | 
			
		||||
 | 
			
		||||
    parser_run = subparsers.add_parser('run', help='Validate the configuration, create a binary, '
 | 
			
		||||
                                                   'upload it, and start MQTT logs.')
 | 
			
		||||
@@ -429,11 +406,6 @@ def parse_args(argv):
 | 
			
		||||
    parser_run.add_argument('--username', help='Manually set the MQTT username for logs.')
 | 
			
		||||
    parser_run.add_argument('--password', help='Manually set the MQTT password for logs.')
 | 
			
		||||
    parser_run.add_argument('--client-id', help='Manually set the client id for logs.')
 | 
			
		||||
    parser_run.add_argument('--escape', help="Escape ANSI color codes for running in dashboard",
 | 
			
		||||
                            action='store_true')
 | 
			
		||||
    parser_run.add_argument('--use-esptoolpy',
 | 
			
		||||
                            help="Use esptool.py for the uploading (only for ESP8266)",
 | 
			
		||||
                            action='store_true')
 | 
			
		||||
 | 
			
		||||
    parser_clean = subparsers.add_parser('clean-mqtt', help="Helper to clear an MQTT topic from "
 | 
			
		||||
                                                            "retain messages.")
 | 
			
		||||
@@ -453,39 +425,46 @@ def parse_args(argv):
 | 
			
		||||
 | 
			
		||||
    dashboard = subparsers.add_parser('dashboard',
 | 
			
		||||
                                      help="Create a simple web server for a dashboard.")
 | 
			
		||||
    dashboard.add_argument("--port", help="The HTTP port to open connections on.", type=int,
 | 
			
		||||
                           default=6052)
 | 
			
		||||
    dashboard.add_argument("--port", help="The HTTP port to open connections on. Defaults to 6052.",
 | 
			
		||||
                           type=int, default=6052)
 | 
			
		||||
    dashboard.add_argument("--password", help="The optional password to require for all requests.",
 | 
			
		||||
                           type=str, default='')
 | 
			
		||||
    dashboard.add_argument("--open-ui", help="Open the dashboard UI in a browser.",
 | 
			
		||||
                           action='store_true')
 | 
			
		||||
    dashboard.add_argument("--hassio",
 | 
			
		||||
                           help="Internal flag used to tell esphomeyaml is started as a Hass.io "
 | 
			
		||||
                                "add-on.",
 | 
			
		||||
                           action="store_true")
 | 
			
		||||
 | 
			
		||||
    subparsers.add_parser('hass-config', help="Dump the configuration entries that should be added"
 | 
			
		||||
                                              "to Home Assistant when not using MQTT discovery.")
 | 
			
		||||
    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:])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run_esphomeyaml(argv):
 | 
			
		||||
    args = parse_args(argv)
 | 
			
		||||
 | 
			
		||||
    setup_log(args.verbose)
 | 
			
		||||
    if args.command in PRE_CONFIG_ACTIONS:
 | 
			
		||||
        try:
 | 
			
		||||
            return PRE_CONFIG_ACTIONS[args.command](args)
 | 
			
		||||
        except ESPHomeYAMLError as e:
 | 
			
		||||
        except EsphomeyamlError as e:
 | 
			
		||||
            _LOGGER.error(e)
 | 
			
		||||
            return 1
 | 
			
		||||
 | 
			
		||||
    core.CONFIG_PATH = args.configuration
 | 
			
		||||
    CORE.config_path = args.configuration
 | 
			
		||||
 | 
			
		||||
    config = read_config(core.CONFIG_PATH)
 | 
			
		||||
    config = read_config(args.verbose)
 | 
			
		||||
    if config is None:
 | 
			
		||||
        return 1
 | 
			
		||||
    CORE.config = config
 | 
			
		||||
 | 
			
		||||
    if args.command in POST_CONFIG_ACTIONS:
 | 
			
		||||
        try:
 | 
			
		||||
            return POST_CONFIG_ACTIONS[args.command](args, config)
 | 
			
		||||
        except ESPHomeYAMLError as e:
 | 
			
		||||
        except EsphomeyamlError as e:
 | 
			
		||||
            _LOGGER.error(e)
 | 
			
		||||
            return 1
 | 
			
		||||
    safe_print(u"Unknown command {}".format(args.command))
 | 
			
		||||
@@ -495,7 +474,7 @@ def run_esphomeyaml(argv):
 | 
			
		||||
def main():
 | 
			
		||||
    try:
 | 
			
		||||
        return run_esphomeyaml(sys.argv)
 | 
			
		||||
    except ESPHomeYAMLError as e:
 | 
			
		||||
    except EsphomeyamlError as e:
 | 
			
		||||
        _LOGGER.error(e)
 | 
			
		||||
        return 1
 | 
			
		||||
    except KeyboardInterrupt:
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,15 @@ import copy
 | 
			
		||||
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import core
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.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
 | 
			
		||||
from esphomeyaml.core import ESPHomeYAMLError
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, add_job, \
 | 
			
		||||
    esphomelib_ns, float_, process_lambda, templatable, uint32, get_variable, PollingComponent, \
 | 
			
		||||
    Action, Component, Trigger
 | 
			
		||||
    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
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, TemplateArguments, add, \
 | 
			
		||||
    get_variable, process_lambda, templatable
 | 
			
		||||
from esphomeyaml.cpp_types import Action, App, Component, PollingComponent, Trigger, \
 | 
			
		||||
    esphomelib_ns, float_, uint32
 | 
			
		||||
from esphomeyaml.util import ServiceRegistry
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -27,41 +26,81 @@ def maybe_simple_id(*validators):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_recursive_condition(value):
 | 
			
		||||
    return CONDITIONS_SCHEMA(value)
 | 
			
		||||
    is_list = isinstance(value, list)
 | 
			
		||||
    value = cv.ensure_list(value)[:]
 | 
			
		||||
    for i, item in enumerate(value):
 | 
			
		||||
        path = [i] if is_list else []
 | 
			
		||||
        item = copy.deepcopy(item)
 | 
			
		||||
        if not isinstance(item, dict):
 | 
			
		||||
            raise vol.Invalid(u"Condition must consist of key-value mapping! Got {}".format(item),
 | 
			
		||||
                              path)
 | 
			
		||||
        key = next((x for x in item if x != CONF_CONDITION_ID), None)
 | 
			
		||||
        if key is None:
 | 
			
		||||
            raise vol.Invalid(u"Key missing from action! Got {}".format(item), path)
 | 
			
		||||
        if key not in CONDITION_REGISTRY:
 | 
			
		||||
            raise vol.Invalid(u"Unable to find condition with the name '{}', is the "
 | 
			
		||||
                              u"component loaded?".format(key), path + [key])
 | 
			
		||||
        item.setdefault(CONF_CONDITION_ID, None)
 | 
			
		||||
        key2 = next((x for x in item if x != CONF_CONDITION_ID and x != key), None)
 | 
			
		||||
        if key2 is not None:
 | 
			
		||||
            raise vol.Invalid(u"Cannot have two conditions in one item. Key '{}' overrides '{}'! "
 | 
			
		||||
                              u"Did you forget to indent the block inside the condition?"
 | 
			
		||||
                              u"".format(key, key2), path)
 | 
			
		||||
        validator = CONDITION_REGISTRY[key][0]
 | 
			
		||||
        try:
 | 
			
		||||
            condition = validator(item[key])
 | 
			
		||||
        except vol.Invalid as err:
 | 
			
		||||
            err.prepend(path)
 | 
			
		||||
            raise err
 | 
			
		||||
        value[i] = {
 | 
			
		||||
            CONF_CONDITION_ID: cv.declare_variable_id(Condition)(item[CONF_CONDITION_ID]),
 | 
			
		||||
            key: condition,
 | 
			
		||||
        }
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_recursive_action(value):
 | 
			
		||||
    is_list = isinstance(value, list)
 | 
			
		||||
    value = cv.ensure_list(value)[:]
 | 
			
		||||
    for i, item in enumerate(value):
 | 
			
		||||
        path = [i] if is_list else []
 | 
			
		||||
        item = copy.deepcopy(item)
 | 
			
		||||
        if not isinstance(item, dict):
 | 
			
		||||
            raise vol.Invalid(u"Action must consist of key-value mapping! Got {}".format(item))
 | 
			
		||||
            raise vol.Invalid(u"Action must consist of key-value mapping! Got {}".format(item),
 | 
			
		||||
                              path)
 | 
			
		||||
        key = next((x for x in item if x != CONF_ACTION_ID), None)
 | 
			
		||||
        if key is None:
 | 
			
		||||
            raise vol.Invalid(u"Key missing from action! Got {}".format(item))
 | 
			
		||||
            raise vol.Invalid(u"Key missing from action! Got {}".format(item), path)
 | 
			
		||||
        if key not in ACTION_REGISTRY:
 | 
			
		||||
            raise vol.Invalid(u"Unable to find action with the name '{}', is the component loaded?"
 | 
			
		||||
                              u"".format(key))
 | 
			
		||||
                              u"".format(key), path + [key])
 | 
			
		||||
        item.setdefault(CONF_ACTION_ID, None)
 | 
			
		||||
        key2 = next((x for x in item if x != CONF_ACTION_ID and x != key), None)
 | 
			
		||||
        if key2 is not None:
 | 
			
		||||
            raise vol.Invalid(u"Cannot have two actions in one item. Key '{}' overrides '{}'! "
 | 
			
		||||
                              u"Did you forget to indent the action?"
 | 
			
		||||
                              u"".format(key, key2))
 | 
			
		||||
                              u"Did you forget to indent the block inside the action?"
 | 
			
		||||
                              u"".format(key, key2), path)
 | 
			
		||||
        validator = ACTION_REGISTRY[key][0]
 | 
			
		||||
        try:
 | 
			
		||||
            action = validator(item[key])
 | 
			
		||||
        except vol.Invalid as err:
 | 
			
		||||
            err.prepend(path)
 | 
			
		||||
            raise err
 | 
			
		||||
        value[i] = {
 | 
			
		||||
            CONF_ACTION_ID: cv.declare_variable_id(Action)(item[CONF_ACTION_ID]),
 | 
			
		||||
            key: validator(item[key])
 | 
			
		||||
            key: action,
 | 
			
		||||
        }
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ACTION_REGISTRY = ServiceRegistry()
 | 
			
		||||
CONDITION_REGISTRY = ServiceRegistry()
 | 
			
		||||
 | 
			
		||||
# pylint: disable=invalid-name
 | 
			
		||||
DelayAction = esphomelib_ns.class_('DelayAction', Action, Component)
 | 
			
		||||
LambdaAction = esphomelib_ns.class_('LambdaAction', Action)
 | 
			
		||||
IfAction = esphomelib_ns.class_('IfAction', Action)
 | 
			
		||||
WhileAction = esphomelib_ns.class_('WhileAction', Action)
 | 
			
		||||
UpdateComponentAction = esphomelib_ns.class_('UpdateComponentAction', Action)
 | 
			
		||||
Automation = esphomelib_ns.class_('Automation')
 | 
			
		||||
 | 
			
		||||
@@ -71,17 +110,6 @@ OrCondition = esphomelib_ns.class_('OrCondition', Condition)
 | 
			
		||||
RangeCondition = esphomelib_ns.class_('RangeCondition', Condition)
 | 
			
		||||
LambdaCondition = esphomelib_ns.class_('LambdaCondition', Condition)
 | 
			
		||||
 | 
			
		||||
CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [cv.templatable({
 | 
			
		||||
    cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(Condition),
 | 
			
		||||
    vol.Optional(CONF_AND): validate_recursive_condition,
 | 
			
		||||
    vol.Optional(CONF_OR): validate_recursive_condition,
 | 
			
		||||
    vol.Optional(CONF_RANGE): vol.All(vol.Schema({
 | 
			
		||||
        vol.Optional(CONF_ABOVE): vol.Coerce(float),
 | 
			
		||||
        vol.Optional(CONF_BELOW): vol.Coerce(float),
 | 
			
		||||
    }), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)),
 | 
			
		||||
    vol.Optional(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
})])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_automation(extra_schema=None, extra_validators=None, single=False):
 | 
			
		||||
    schema = AUTOMATION_SCHEMA.extend(extra_schema or {})
 | 
			
		||||
@@ -122,63 +150,63 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
 | 
			
		||||
AUTOMATION_SCHEMA = vol.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): CONDITIONS_SCHEMA,
 | 
			
		||||
    vol.Optional(CONF_IF): validate_recursive_condition,
 | 
			
		||||
    vol.Required(CONF_THEN): validate_recursive_action,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
AND_CONDITION_SCHEMA = validate_recursive_condition
 | 
			
		||||
 | 
			
		||||
def build_condition(config, arg_type):
 | 
			
		||||
    template_arg = TemplateArguments(arg_type)
 | 
			
		||||
    if isinstance(config, core.Lambda):
 | 
			
		||||
        lambda_ = None
 | 
			
		||||
        for lambda_ in process_lambda(config, [(arg_type, 'x')]):
 | 
			
		||||
 | 
			
		||||
@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):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = AndCondition.new(template_arg, conditions)
 | 
			
		||||
    type = AndCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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):
 | 
			
		||||
        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({
 | 
			
		||||
    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):
 | 
			
		||||
        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_):
 | 
			
		||||
            yield
 | 
			
		||||
        yield LambdaCondition.new(template_arg, lambda_)
 | 
			
		||||
    elif CONF_AND in config:
 | 
			
		||||
        yield AndCondition.new(template_arg, build_conditions(config[CONF_AND], template_arg))
 | 
			
		||||
    elif CONF_OR in config:
 | 
			
		||||
        yield OrCondition.new(template_arg, build_conditions(config[CONF_OR], template_arg))
 | 
			
		||||
    elif CONF_LAMBDA in config:
 | 
			
		||||
        lambda_ = None
 | 
			
		||||
        for lambda_ in process_lambda(config[CONF_LAMBDA], [(arg_type, 'x')]):
 | 
			
		||||
        condition.set_min(template_)
 | 
			
		||||
    if CONF_BELOW in config:
 | 
			
		||||
        for template_ in templatable(config[CONF_BELOW], arg_type, float_):
 | 
			
		||||
            yield
 | 
			
		||||
        yield LambdaCondition.new(template_arg, lambda_)
 | 
			
		||||
    elif CONF_RANGE in config:
 | 
			
		||||
        conf = config[CONF_RANGE]
 | 
			
		||||
        rhs = RangeCondition.new(template_arg)
 | 
			
		||||
        type = RangeCondition.template(template_arg)
 | 
			
		||||
        condition = Pvariable(config[CONF_CONDITION_ID], rhs, type=type)
 | 
			
		||||
        if CONF_ABOVE in conf:
 | 
			
		||||
            template_ = None
 | 
			
		||||
            for template_ in templatable(conf[CONF_ABOVE], arg_type, float_):
 | 
			
		||||
                yield
 | 
			
		||||
            condition.set_min(template_)
 | 
			
		||||
        if CONF_BELOW in conf:
 | 
			
		||||
            template_ = None
 | 
			
		||||
            for template_ in templatable(conf[CONF_BELOW], arg_type, float_):
 | 
			
		||||
                yield
 | 
			
		||||
            condition.set_max(template_)
 | 
			
		||||
        yield condition
 | 
			
		||||
    else:
 | 
			
		||||
        raise ESPHomeYAMLError(u"Unsupported condition {}".format(config))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_conditions(config, arg_type):
 | 
			
		||||
    conditions = []
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        condition = None
 | 
			
		||||
        for condition in build_condition(conf, arg_type):
 | 
			
		||||
            yield None
 | 
			
		||||
        conditions.append(condition)
 | 
			
		||||
    yield ArrayInitializer(*conditions)
 | 
			
		||||
        condition.set_max(template_)
 | 
			
		||||
    yield condition
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 = TemplateArguments(arg_type)
 | 
			
		||||
def delay_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    rhs = App.register_component(DelayAction.new(template_arg))
 | 
			
		||||
    type = DelayAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
@@ -196,8 +224,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def if_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for conditions in build_conditions(config[CONF_CONDITION], arg_type):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = IfAction.new(template_arg, conditions)
 | 
			
		||||
@@ -214,12 +241,30 @@ def if_action_to_code(config, action_id, arg_type):
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
WHILE_ACTION_SCHEMA = vol.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):
 | 
			
		||||
        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):
 | 
			
		||||
        yield None
 | 
			
		||||
    add(action.add_then(actions))
 | 
			
		||||
    yield action
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 = TemplateArguments(arg_type)
 | 
			
		||||
def lambda_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for lambda_ in process_lambda(config, [(arg_type, 'x')]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = LambdaAction.new(template_arg, lambda_)
 | 
			
		||||
@@ -227,6 +272,18 @@ def lambda_action_to_code(config, action_id, arg_type):
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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')]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = LambdaCondition.new(template_arg, lambda_)
 | 
			
		||||
    type = LambdaCondition.template(template_arg)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_COMPONENT_UPDATE = 'component.update'
 | 
			
		||||
COMPONENT_UPDATE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(PollingComponent),
 | 
			
		||||
@@ -234,8 +291,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 = TemplateArguments(arg_type)
 | 
			
		||||
def component_update_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = UpdateComponentAction.new(var)
 | 
			
		||||
@@ -248,7 +304,8 @@ def build_action(full_config, arg_type):
 | 
			
		||||
    key, config = next((k, v) for k, v in full_config.items() if k in ACTION_REGISTRY)
 | 
			
		||||
 | 
			
		||||
    builder = ACTION_REGISTRY[key][1]
 | 
			
		||||
    for result in builder(config, action_id, arg_type):
 | 
			
		||||
    template_arg = TemplateArguments(arg_type)
 | 
			
		||||
    for result in builder(config, action_id, arg_type, template_arg):
 | 
			
		||||
        yield None
 | 
			
		||||
    yield result
 | 
			
		||||
 | 
			
		||||
@@ -263,6 +320,26 @@ def build_actions(config, arg_type):
 | 
			
		||||
    yield ArrayInitializer(*actions, multiline=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_condition(full_config, arg_type):
 | 
			
		||||
    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):
 | 
			
		||||
        yield None
 | 
			
		||||
    yield result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_conditions(config, arg_type):
 | 
			
		||||
    conditions = []
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for condition in build_condition(conf, arg_type):
 | 
			
		||||
            yield None
 | 
			
		||||
        conditions.append(condition)
 | 
			
		||||
    yield ArrayInitializer(*conditions, multiline=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_automation_(trigger, arg_type, config):
 | 
			
		||||
    rhs = App.make_automation(TemplateArguments(arg_type), trigger)
 | 
			
		||||
    type = Automation.template(arg_type)
 | 
			
		||||
@@ -280,4 +357,4 @@ def build_automation_(trigger, arg_type, config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_automation(trigger, arg_type, config):
 | 
			
		||||
    add_job(build_automation_, trigger, arg_type, config)
 | 
			
		||||
    CORE.add_job(build_automation_, trigger, arg_type, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,27 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.components import sensor, i2c
 | 
			
		||||
from esphomeyaml.components import i2c, sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_ID
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
ADS1115Component = sensor.sensor_ns.class_('ADS1115Component', Component, i2c.I2CDevice)
 | 
			
		||||
 | 
			
		||||
ADS1115_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(ADS1115Component),
 | 
			
		||||
    vol.Required(CONF_ADDRESS): cv.i2c_address,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        rhs = App.make_ads1115_component(conf[CONF_ADDRESS])
 | 
			
		||||
        var = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        setup_component(var, conf)
 | 
			
		||||
    rhs = App.make_ads1115_component(config[CONF_ADDRESS])
 | 
			
		||||
    var = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    setup_component(var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,19 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import automation, core
 | 
			
		||||
from esphomeyaml.automation import maybe_simple_id, CONDITION_REGISTRY, Condition
 | 
			
		||||
from esphomeyaml.components import mqtt
 | 
			
		||||
from esphomeyaml.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_DELAYED_OFF, CONF_DELAYED_ON, CONF_DEVICE_CLASS, CONF_FILTERS, \
 | 
			
		||||
    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_STATE, \
 | 
			
		||||
    CONF_TIMING, CONF_TRIGGER_ID
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, NoArg, Pvariable, StructInitializer, add, \
 | 
			
		||||
    add_job, bool_, esphomelib_ns, process_lambda, setup_mqtt_component, Nameable, Trigger, \
 | 
			
		||||
    Component
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import process_lambda, ArrayInitializer, add, Pvariable, \
 | 
			
		||||
    StructInitializer, get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import esphomelib_ns, Nameable, Trigger, NoArg, Component, App, bool_
 | 
			
		||||
 | 
			
		||||
DEVICE_CLASSES = [
 | 
			
		||||
    '', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
 | 
			
		||||
@@ -25,6 +28,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
binary_sensor_ns = esphomelib_ns.namespace('binary_sensor')
 | 
			
		||||
BinarySensor = binary_sensor_ns.class_('BinarySensor', Nameable)
 | 
			
		||||
BinarySensorPtr = BinarySensor.operator('ptr')
 | 
			
		||||
MQTTBinarySensorComponent = binary_sensor_ns.class_('MQTTBinarySensorComponent', mqtt.MQTTComponent)
 | 
			
		||||
 | 
			
		||||
# Triggers
 | 
			
		||||
@@ -35,6 +39,9 @@ DoubleClickTrigger = binary_sensor_ns.class_('DoubleClickTrigger', Trigger.templ
 | 
			
		||||
MultiClickTrigger = binary_sensor_ns.class_('MultiClickTrigger', Trigger.template(NoArg), Component)
 | 
			
		||||
MultiClickTriggerEvent = binary_sensor_ns.struct('MultiClickTriggerEvent')
 | 
			
		||||
 | 
			
		||||
# Condition
 | 
			
		||||
BinarySensorCondition = binary_sensor_ns.class_('BinarySensorCondition', Condition)
 | 
			
		||||
 | 
			
		||||
# Filters
 | 
			
		||||
Filter = binary_sensor_ns.class_('Filter')
 | 
			
		||||
DelayedOnFilter = binary_sensor_ns.class_('DelayedOnFilter', Filter, Component)
 | 
			
		||||
@@ -269,14 +276,14 @@ def setup_binary_sensor(binary_sensor_obj, mqtt_obj, config):
 | 
			
		||||
                                  has_side_effects=False)
 | 
			
		||||
    mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj,
 | 
			
		||||
                         has_side_effects=False)
 | 
			
		||||
    add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config)
 | 
			
		||||
    CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_binary_sensor(var, config):
 | 
			
		||||
    binary_sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True)
 | 
			
		||||
    rhs = App.register_binary_sensor(binary_sensor_var)
 | 
			
		||||
    mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True)
 | 
			
		||||
    add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config)
 | 
			
		||||
    CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def core_to_hass_config(data, config):
 | 
			
		||||
@@ -290,3 +297,33 @@ def core_to_hass_config(data, config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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):
 | 
			
		||||
    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)
 | 
			
		||||
    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),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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):
 | 
			
		||||
    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)
 | 
			
		||||
    yield Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								esphomeyaml/components/binary_sensor/custom.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								esphomeyaml/components/binary_sensor/custom.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.components import binary_sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA
 | 
			
		||||
from esphomeyaml.cpp_generator import process_lambda, variable
 | 
			
		||||
from esphomeyaml.cpp_types import std_vector
 | 
			
		||||
 | 
			
		||||
CustomBinarySensorConstructor = binary_sensor.binary_sensor_ns.class_(
 | 
			
		||||
    'CustomBinarySensorConstructor')
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = binary_sensor.PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(CustomBinarySensorConstructor),
 | 
			
		||||
    vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Required(CONF_BINARY_SENSORS):
 | 
			
		||||
        vol.All(cv.ensure_list, [binary_sensor.BINARY_SENSOR_SCHEMA.extend({
 | 
			
		||||
            cv.GenerateID(): cv.declare_variable_id(binary_sensor.BinarySensor),
 | 
			
		||||
        })]),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for template_ in process_lambda(config[CONF_LAMBDA], [],
 | 
			
		||||
                                    return_type=std_vector.template(binary_sensor.BinarySensorPtr)):
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
    rhs = CustomBinarySensorConstructor(template_)
 | 
			
		||||
    custom = variable(config[CONF_ID], rhs)
 | 
			
		||||
    for i, sens in enumerate(config[CONF_BINARY_SENSORS]):
 | 
			
		||||
        binary_sensor.register_binary_sensor(custom.get_binary_sensor(i), sens)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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]]
 | 
			
		||||
@@ -5,7 +5,8 @@ from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLE
 | 
			
		||||
    make_address_array
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
 | 
			
		||||
from esphomeyaml.helpers import esphomelib_ns, get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import esphomelib_ns
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['esp32_ble_tracker']
 | 
			
		||||
ESP32BLEPresenceDevice = esphomelib_ns.class_('ESP32BLEPresenceDevice', binary_sensor.BinarySensor)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,8 @@ import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import binary_sensor
 | 
			
		||||
from esphomeyaml.components.esp32_touch import ESP32TouchComponent
 | 
			
		||||
from esphomeyaml.const import CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32
 | 
			
		||||
from esphomeyaml.helpers import get_variable, global_ns
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import global_ns
 | 
			
		||||
from esphomeyaml.pins import validate_gpio_pin
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,9 @@ import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import binary_sensor
 | 
			
		||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN
 | 
			
		||||
from esphomeyaml.helpers import App, gpio_input_pin_expression, variable, Application, \
 | 
			
		||||
    setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, Component, App
 | 
			
		||||
 | 
			
		||||
MakeGPIOBinarySensor = Application.struct('MakeGPIOBinarySensor')
 | 
			
		||||
GPIOBinarySensorComponent = binary_sensor.binary_sensor_ns.class_('GPIOBinarySensorComponent',
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ from esphomeyaml.components import binary_sensor, display
 | 
			
		||||
from esphomeyaml.components.display.nextion import Nextion
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_COMPONENT_ID, CONF_NAME, CONF_PAGE_ID
 | 
			
		||||
from esphomeyaml.helpers import get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['display']
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +22,6 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    hub = None
 | 
			
		||||
    for hub in get_variable(config[CONF_NEXTION_ID]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = hub.make_touch_component(config[CONF_NAME], config[CONF_PAGE_ID],
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ from esphomeyaml.components import binary_sensor
 | 
			
		||||
from esphomeyaml.components.pn532 import PN532Component
 | 
			
		||||
from esphomeyaml.const import CONF_NAME, CONF_UID
 | 
			
		||||
from esphomeyaml.core import HexInt
 | 
			
		||||
from esphomeyaml.helpers import ArrayInitializer, get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, ArrayInitializer
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['pn532']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ import voluptuous as vol
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import binary_sensor, rdm6300
 | 
			
		||||
from esphomeyaml.const import CONF_NAME, CONF_UID
 | 
			
		||||
from esphomeyaml.helpers import get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['rdm6300']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAN
 | 
			
		||||
    CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \
 | 
			
		||||
    CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \
 | 
			
		||||
    CONF_STATE
 | 
			
		||||
from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, get_variable, Pvariable
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['remote_receiver']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import binary_sensor
 | 
			
		||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME
 | 
			
		||||
from esphomeyaml.helpers import App, Application, variable, setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, Component, App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['mqtt']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,9 @@ import voluptuous as vol
 | 
			
		||||
from esphomeyaml.components import binary_sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME
 | 
			
		||||
from esphomeyaml.helpers import App, Application, add, bool_, optional, process_lambda, variable, \
 | 
			
		||||
    setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable, process_lambda, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, Component, App, optional, bool_
 | 
			
		||||
 | 
			
		||||
MakeTemplateBinarySensor = Application.struct('MakeTemplateBinarySensor')
 | 
			
		||||
TemplateBinarySensor = binary_sensor.binary_sensor_ns.class_('TemplateBinarySensor',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
 | 
			
		||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
from esphomeyaml.components import mqtt
 | 
			
		||||
from esphomeyaml.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_INTERNAL
 | 
			
		||||
from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component, add, \
 | 
			
		||||
    TemplateArguments, get_variable, Action, Nameable
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import Action, Nameable, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
@@ -54,8 +55,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def cover_open_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_open_action(template_arg)
 | 
			
		||||
@@ -70,8 +70,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def cover_close_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_close_action(template_arg)
 | 
			
		||||
@@ -86,8 +85,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def cover_stop_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_stop_action(template_arg)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,9 @@ from esphomeyaml import automation
 | 
			
		||||
from esphomeyaml.components import cover
 | 
			
		||||
from esphomeyaml.const import CONF_CLOSE_ACTION, CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, \
 | 
			
		||||
    CONF_OPEN_ACTION, CONF_STOP_ACTION, CONF_OPTIMISTIC
 | 
			
		||||
from esphomeyaml.helpers import App, Application, NoArg, add, process_lambda, variable, optional, \
 | 
			
		||||
    setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable, process_lambda, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, App, optional, NoArg
 | 
			
		||||
 | 
			
		||||
MakeTemplateCover = Application.struct('MakeTemplateCover')
 | 
			
		||||
TemplateCover = cover.cover_ns.class_('TemplateCover', cover.Cover)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								esphomeyaml/components/custom_component.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								esphomeyaml/components/custom_component.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_COMPONENTS
 | 
			
		||||
from esphomeyaml.cpp_generator import process_lambda, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Component, ComponentPtr, esphomelib_ns, std_vector
 | 
			
		||||
 | 
			
		||||
CustomComponentConstructor = esphomelib_ns.class_('CustomComponentConstructor')
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(CustomComponentConstructor),
 | 
			
		||||
    vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Optional(CONF_COMPONENTS): vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
        cv.GenerateID(): cv.declare_variable_id(Component)
 | 
			
		||||
    }).extend(cv.COMPONENT_SCHEMA.schema)]),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for template_ in process_lambda(config[CONF_LAMBDA], [],
 | 
			
		||||
                                    return_type=std_vector.template(ComponentPtr)):
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
    rhs = CustomComponentConstructor(template_)
 | 
			
		||||
    custom = variable(config[CONF_ID], rhs)
 | 
			
		||||
    for i, comp in enumerate(config.get(CONF_COMPONENTS, [])):
 | 
			
		||||
        setup_component(custom.get_component(i), comp)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_CUSTOM_COMPONENT'
 | 
			
		||||
@@ -1,25 +1,27 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_PIN, CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, setup_component, PollingComponent
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent
 | 
			
		||||
 | 
			
		||||
DallasComponent = sensor.sensor_ns.class_('DallasComponent', PollingComponent)
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(DallasComponent),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.input_output_pin,
 | 
			
		||||
    vol.Required(CONF_PIN): pins.input_pullup_pin,
 | 
			
		||||
    vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL))
 | 
			
		||||
        var = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        setup_component(var, conf)
 | 
			
		||||
    rhs = App.make_dallas_component(config[CONF_PIN], config.get(CONF_UPDATE_INTERVAL))
 | 
			
		||||
    var = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    setup_component(var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.helpers import App, add
 | 
			
		||||
from esphomeyaml.cpp_generator import add
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['logger']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,11 @@ import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import config_validation as cv, pins
 | 
			
		||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \
 | 
			
		||||
    CONF_SLEEP_DURATION, CONF_WAKEUP_PIN, CONF_MODE, CONF_PINS
 | 
			
		||||
from esphomeyaml.helpers import Action, App, Component, Pvariable, TemplateArguments, add, \
 | 
			
		||||
    esphomelib_ns, get_variable, gpio_input_pin_expression, setup_component, global_ns, \
 | 
			
		||||
    StructInitializer
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_MODE, CONF_NUMBER, CONF_PINS, CONF_RUN_CYCLES, \
 | 
			
		||||
    CONF_RUN_DURATION, CONF_SLEEP_DURATION, CONF_WAKEUP_PIN
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, StructInitializer, add, get_variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Action, App, Component, esphomelib_ns, global_ns
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_pin_number(value):
 | 
			
		||||
@@ -95,8 +95,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def deep_sleep_enter_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_enter_deep_sleep_action(template_arg)
 | 
			
		||||
@@ -111,8 +110,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def deep_sleep_prevent_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_prevent_deep_sleep_action(template_arg)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,9 @@ import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_LAMBDA, CONF_ROTATION, CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import add, add_job, esphomelib_ns
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import add
 | 
			
		||||
from esphomeyaml.cpp_types import esphomelib_ns
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
@@ -50,7 +52,7 @@ def setup_display_core_(display_var, config):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setup_display(display_var, config):
 | 
			
		||||
    add_job(setup_display_core_, display_var, config)
 | 
			
		||||
    CORE.add_job(setup_display_core_, display_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_DISPLAY'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,13 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import display
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_DATA_PINS, CONF_DIMENSIONS, CONF_ENABLE_PIN, CONF_ID, \
 | 
			
		||||
    CONF_LAMBDA, CONF_RS_PIN, CONF_RW_PIN
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, process_lambda, \
 | 
			
		||||
    setup_component, PollingComponent
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, process_lambda
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent
 | 
			
		||||
 | 
			
		||||
LCDDisplay = display.display_ns.class_('LCDDisplay', PollingComponent)
 | 
			
		||||
LCDDisplayRef = LCDDisplay.operator('ref')
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import display, i2c
 | 
			
		||||
from esphomeyaml.components.display.lcd_gpio import LCDDisplayRef, validate_lcd_dimensions, \
 | 
			
		||||
    LCDDisplay
 | 
			
		||||
from esphomeyaml.components.display.lcd_gpio import LCDDisplay, LCDDisplayRef, \
 | 
			
		||||
    validate_lcd_dimensions
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_DIMENSIONS, CONF_ID, CONF_LAMBDA
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, process_lambda, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, process_lambda
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import display, spi
 | 
			
		||||
from esphomeyaml.components.spi import SPIComponent
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_INTENSITY, CONF_LAMBDA, CONF_NUM_CHIPS, \
 | 
			
		||||
    CONF_SPI_ID
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression, \
 | 
			
		||||
    process_lambda, setup_component, PollingComponent
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, get_variable, process_lambda
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['spi']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,9 @@ from esphomeyaml.components import display, uart
 | 
			
		||||
from esphomeyaml.components.uart import UARTComponent
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_UART_ID
 | 
			
		||||
from esphomeyaml.helpers import App, PollingComponent, Pvariable, add, get_variable, \
 | 
			
		||||
    process_lambda, \
 | 
			
		||||
    setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, get_variable, process_lambda
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['uart']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import display
 | 
			
		||||
from esphomeyaml.components.display import ssd1306_spi
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, \
 | 
			
		||||
    CONF_MODEL, CONF_RESET_PIN, CONF_LAMBDA
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, \
 | 
			
		||||
    gpio_output_pin_expression, process_lambda, setup_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_LAMBDA, CONF_MODEL, \
 | 
			
		||||
    CONF_RESET_PIN
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, process_lambda
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import display, spi
 | 
			
		||||
from esphomeyaml.components.spi import SPIComponent
 | 
			
		||||
from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, \
 | 
			
		||||
    CONF_ID, CONF_MODEL, \
 | 
			
		||||
    CONF_RESET_PIN, CONF_SPI_ID, CONF_LAMBDA
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, \
 | 
			
		||||
    gpio_output_pin_expression, process_lambda, setup_component, PollingComponent
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, CONF_ID, CONF_LAMBDA, \
 | 
			
		||||
    CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add, get_variable, process_lambda
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['spi']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,10 @@ from esphomeyaml.components import display, spi
 | 
			
		||||
from esphomeyaml.components.spi import SPIComponent
 | 
			
		||||
from esphomeyaml.const import CONF_BUSY_PIN, CONF_CS_PIN, CONF_DC_PIN, CONF_FULL_UPDATE_EVERY, \
 | 
			
		||||
    CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_input_pin_expression, \
 | 
			
		||||
    gpio_output_pin_expression, process_lambda, setup_component, PollingComponent
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, Pvariable, process_lambda, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, gpio_input_pin_expression, \
 | 
			
		||||
    setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import PollingComponent, App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['spi']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,9 @@ import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, CONF_TYPE, CONF_UUID, ESP_PLATFORM_ESP32
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, Component, Pvariable, RawExpression, add, \
 | 
			
		||||
    esphomelib_ns, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, RawExpression, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,9 @@ from esphomeyaml import config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32
 | 
			
		||||
from esphomeyaml.core import HexInt
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, ArrayInitializer, \
 | 
			
		||||
    setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,13 @@ import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import config_validation as cv
 | 
			
		||||
from esphomeyaml.components import binary_sensor
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_SETUP_MODE, CONF_IIR_FILTER, \
 | 
			
		||||
    CONF_SLEEP_DURATION, CONF_MEASUREMENT_DURATION, CONF_LOW_VOLTAGE_REFERENCE, \
 | 
			
		||||
    CONF_HIGH_VOLTAGE_REFERENCE, CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32
 | 
			
		||||
from esphomeyaml.const import CONF_HIGH_VOLTAGE_REFERENCE, CONF_ID, CONF_IIR_FILTER, \
 | 
			
		||||
    CONF_LOW_VOLTAGE_REFERENCE, CONF_MEASUREMENT_DURATION, CONF_SETUP_MODE, CONF_SLEEP_DURATION, \
 | 
			
		||||
    CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32
 | 
			
		||||
from esphomeyaml.core import TimePeriod
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, global_ns, setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, global_ns
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
 | 
			
		||||
@@ -19,6 +21,7 @@ def validate_voltage(values):
 | 
			
		||||
        if not value.endswith('V'):
 | 
			
		||||
            value += 'V'
 | 
			
		||||
        return cv.one_of(*values)(value)
 | 
			
		||||
 | 
			
		||||
    return validator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
 | 
			
		||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
from esphomeyaml.components import mqtt
 | 
			
		||||
from esphomeyaml.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_OSCILLATION_COMMAND_TOPIC, \
 | 
			
		||||
    CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_INTERNAL, \
 | 
			
		||||
    CONF_SPEED, CONF_OSCILLATING, CONF_OSCILLATION_OUTPUT, CONF_NAME
 | 
			
		||||
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component, \
 | 
			
		||||
    TemplateArguments, get_variable, templatable, bool_, Action, Nameable, Component
 | 
			
		||||
from esphomeyaml.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 esphomeyaml.cpp_generator import add, Pvariable, get_variable, templatable
 | 
			
		||||
from esphomeyaml.cpp_types import Application, Component, Nameable, esphomelib_ns, Action, bool_
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +39,6 @@ FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
FAN_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FAN_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FAN_SPEEDS = {
 | 
			
		||||
    'OFF': FAN_SPEED_OFF,
 | 
			
		||||
    'LOW': FAN_SPEED_LOW,
 | 
			
		||||
@@ -70,7 +70,6 @@ def setup_fan(fan_obj, mqtt_obj, config):
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_FAN'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_FAN_TOGGLE = 'fan.toggle'
 | 
			
		||||
FAN_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(FanState),
 | 
			
		||||
@@ -78,8 +77,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def fan_toggle_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_toggle_action(template_arg)
 | 
			
		||||
@@ -94,8 +92,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def fan_turn_off_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_off_action(template_arg)
 | 
			
		||||
@@ -112,8 +109,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def fan_turn_on_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_on_action(template_arg)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,9 @@ import voluptuous as vol
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import fan, output
 | 
			
		||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT
 | 
			
		||||
from esphomeyaml.helpers import App, add, get_variable, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan),
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,8 @@ from esphomeyaml.components import fan, mqtt, output
 | 
			
		||||
from esphomeyaml.const import CONF_HIGH, CONF_LOW, CONF_MAKE_ID, CONF_MEDIUM, CONF_NAME, \
 | 
			
		||||
    CONF_OSCILLATION_OUTPUT, CONF_OUTPUT, CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, \
 | 
			
		||||
    CONF_SPEED_STATE_TOPIC
 | 
			
		||||
from esphomeyaml.helpers import App, add, get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable, add
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,16 @@
 | 
			
		||||
# coding=utf-8
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import core
 | 
			
		||||
from esphomeyaml.components import display
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE
 | 
			
		||||
from esphomeyaml.core import HexInt
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \
 | 
			
		||||
    relative_path
 | 
			
		||||
from esphomeyaml.core import CORE, HexInt
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, MockObj, Pvariable, RawExpression, add
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['display']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
Font = display.display_ns.class_('Font')
 | 
			
		||||
Glyph = display.display_ns.class_('Glyph')
 | 
			
		||||
@@ -76,46 +77,45 @@ FONT_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(validate_pillow_installed, cv.ensure_list, [FONT_SCHEMA])
 | 
			
		||||
CONFIG_SCHEMA = vol.All(validate_pillow_installed, FONT_SCHEMA)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    from PIL import ImageFont
 | 
			
		||||
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        path = relative_path(conf[CONF_FILE])
 | 
			
		||||
        try:
 | 
			
		||||
            font = ImageFont.truetype(path, conf[CONF_SIZE])
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            raise core.ESPHomeYAMLError(u"Could not load truetype file {}: {}".format(path, e))
 | 
			
		||||
    path = CORE.relative_path(config[CONF_FILE])
 | 
			
		||||
    try:
 | 
			
		||||
        font = ImageFont.truetype(path, config[CONF_SIZE])
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        raise core.EsphomeyamlError(u"Could not load truetype file {}: {}".format(path, e))
 | 
			
		||||
 | 
			
		||||
        ascent, descent = font.getmetrics()
 | 
			
		||||
    ascent, descent = font.getmetrics()
 | 
			
		||||
 | 
			
		||||
        glyph_args = {}
 | 
			
		||||
        data = []
 | 
			
		||||
        for glyph in conf[CONF_GLYPHS]:
 | 
			
		||||
            mask = font.getmask(glyph, mode='1')
 | 
			
		||||
            _, (offset_x, offset_y) = font.font.getsize(glyph)
 | 
			
		||||
            width, height = mask.size
 | 
			
		||||
            width8 = ((width + 7) // 8) * 8
 | 
			
		||||
            glyph_data = [0 for _ in range(height * width8 // 8)]  # noqa: F812
 | 
			
		||||
            for y in range(height):
 | 
			
		||||
                for x in range(width):
 | 
			
		||||
                    if not mask.getpixel((x, y)):
 | 
			
		||||
                        continue
 | 
			
		||||
                    pos = x + y * width8
 | 
			
		||||
                    glyph_data[pos // 8] |= 0x80 >> (pos % 8)
 | 
			
		||||
            glyph_args[glyph] = (len(data), offset_x, offset_y, width, height)
 | 
			
		||||
            data += glyph_data
 | 
			
		||||
    glyph_args = {}
 | 
			
		||||
    data = []
 | 
			
		||||
    for glyph in config[CONF_GLYPHS]:
 | 
			
		||||
        mask = font.getmask(glyph, mode='1')
 | 
			
		||||
        _, (offset_x, offset_y) = font.font.getsize(glyph)
 | 
			
		||||
        width, height = mask.size
 | 
			
		||||
        width8 = ((width + 7) // 8) * 8
 | 
			
		||||
        glyph_data = [0 for _ in range(height * width8 // 8)]  # noqa: F812
 | 
			
		||||
        for y in range(height):
 | 
			
		||||
            for x in range(width):
 | 
			
		||||
                if not mask.getpixel((x, y)):
 | 
			
		||||
                    continue
 | 
			
		||||
                pos = x + y * width8
 | 
			
		||||
                glyph_data[pos // 8] |= 0x80 >> (pos % 8)
 | 
			
		||||
        glyph_args[glyph] = (len(data), offset_x, offset_y, width, height)
 | 
			
		||||
        data += glyph_data
 | 
			
		||||
 | 
			
		||||
        raw_data = MockObj(conf[CONF_RAW_DATA_ID])
 | 
			
		||||
        add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format(
 | 
			
		||||
            raw_data, len(data),
 | 
			
		||||
            ArrayInitializer(*[HexInt(x) for x in data], multiline=False))))
 | 
			
		||||
    raw_data = MockObj(config[CONF_RAW_DATA_ID])
 | 
			
		||||
    add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format(
 | 
			
		||||
        raw_data, len(data),
 | 
			
		||||
        ArrayInitializer(*[HexInt(x) for x in data], multiline=False))))
 | 
			
		||||
 | 
			
		||||
        glyphs = []
 | 
			
		||||
        for glyph in conf[CONF_GLYPHS]:
 | 
			
		||||
            glyphs.append(Glyph(glyph, raw_data, *glyph_args[glyph]))
 | 
			
		||||
    glyphs = []
 | 
			
		||||
    for glyph in config[CONF_GLYPHS]:
 | 
			
		||||
        glyphs.append(Glyph(glyph, raw_data, *glyph_args[glyph]))
 | 
			
		||||
 | 
			
		||||
        rhs = App.make_font(ArrayInitializer(*glyphs), ascent, ascent + descent)
 | 
			
		||||
        Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
    rhs = App.make_font(ArrayInitializer(*glyphs), ascent, ascent + descent)
 | 
			
		||||
    Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,34 +2,34 @@ import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE
 | 
			
		||||
from esphomeyaml.helpers import App, Component, Pvariable, RawExpression, TemplateArguments, add, \
 | 
			
		||||
    esphomelib_ns, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, RawExpression, TemplateArguments, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
GlobalVariableComponent = esphomelib_ns.class_('GlobalVariableComponent', Component)
 | 
			
		||||
 | 
			
		||||
GLOBAL_VAR_SCHEMA = vol.Schema({
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.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,
 | 
			
		||||
    vol.Optional(CONF_RESTORE_VALUE): cv.boolean,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [GLOBAL_VAR_SCHEMA])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        type_ = RawExpression(conf[CONF_TYPE])
 | 
			
		||||
        template_args = TemplateArguments(type_)
 | 
			
		||||
        res_type = GlobalVariableComponent.template(template_args)
 | 
			
		||||
        initial_value = None
 | 
			
		||||
        if CONF_INITIAL_VALUE in conf:
 | 
			
		||||
            initial_value = RawExpression(conf[CONF_INITIAL_VALUE])
 | 
			
		||||
        rhs = App.Pmake_global_variable(template_args, initial_value)
 | 
			
		||||
        glob = Pvariable(conf[CONF_ID], rhs, type=res_type)
 | 
			
		||||
    type_ = RawExpression(config[CONF_TYPE])
 | 
			
		||||
    template_args = TemplateArguments(type_)
 | 
			
		||||
    res_type = GlobalVariableComponent.template(template_args)
 | 
			
		||||
    initial_value = None
 | 
			
		||||
    if CONF_INITIAL_VALUE in config:
 | 
			
		||||
        initial_value = RawExpression(config[CONF_INITIAL_VALUE])
 | 
			
		||||
    rhs = App.Pmake_global_variable(template_args, initial_value)
 | 
			
		||||
    glob = Pvariable(config[CONF_ID], rhs, type=res_type)
 | 
			
		||||
 | 
			
		||||
        if conf.get(CONF_RESTORE_VALUE, False):
 | 
			
		||||
            hash_ = hash(conf[CONF_ID].id) % 2**32
 | 
			
		||||
            add(glob.set_restore_value(hash_))
 | 
			
		||||
    if config.get(CONF_RESTORE_VALUE, False):
 | 
			
		||||
        hash_ = hash(config[CONF_ID].id) % 2**32
 | 
			
		||||
        add(glob.set_restore_value(hash_))
 | 
			
		||||
 | 
			
		||||
        setup_component(glob, conf)
 | 
			
		||||
    setup_component(glob, config)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,20 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID, \
 | 
			
		||||
    CONF_RECEIVE_TIMEOUT
 | 
			
		||||
from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns, setup_component, Component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_FREQUENCY, CONF_ID, CONF_RECEIVE_TIMEOUT, CONF_SCAN, CONF_SCL, \
 | 
			
		||||
    CONF_SDA
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
I2CComponent = esphomelib_ns.class_('I2CComponent', Component)
 | 
			
		||||
I2CDevice = pins.I2CDevice
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(I2CComponent),
 | 
			
		||||
    vol.Required(CONF_SDA, default='SDA'): pins.input_output_pin,
 | 
			
		||||
    vol.Required(CONF_SCL, default='SCL'): pins.input_output_pin,
 | 
			
		||||
    vol.Optional(CONF_SDA, default='SDA'): pins.input_pullup_pin,
 | 
			
		||||
    vol.Optional(CONF_SCL, default='SCL'): pins.input_pullup_pin,
 | 
			
		||||
    vol.Optional(CONF_FREQUENCY): vol.All(cv.frequency, vol.Range(min=0, min_included=False)),
 | 
			
		||||
    vol.Optional(CONF_SCAN): cv.boolean,
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,17 +3,18 @@ import logging
 | 
			
		||||
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import core
 | 
			
		||||
from esphomeyaml.components import display, font
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE
 | 
			
		||||
from esphomeyaml.core import HexInt
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add, \
 | 
			
		||||
    relative_path
 | 
			
		||||
from esphomeyaml.core import CORE, HexInt
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, MockObj, Pvariable, RawExpression, add
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
_LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['display']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
Image_ = display.display_ns.class_('Image')
 | 
			
		||||
 | 
			
		||||
@@ -26,40 +27,39 @@ IMAGE_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(font.validate_pillow_installed, cv.ensure_list, [IMAGE_SCHEMA])
 | 
			
		||||
CONFIG_SCHEMA = vol.All(font.validate_pillow_installed, IMAGE_SCHEMA)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    from PIL import Image
 | 
			
		||||
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        path = relative_path(conf[CONF_FILE])
 | 
			
		||||
        try:
 | 
			
		||||
            image = Image.open(path)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            raise core.ESPHomeYAMLError(u"Could not load image file {}: {}".format(path, e))
 | 
			
		||||
    path = CORE.relative_path(config[CONF_FILE])
 | 
			
		||||
    try:
 | 
			
		||||
        image = Image.open(path)
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        raise core.EsphomeyamlError(u"Could not load image file {}: {}".format(path, e))
 | 
			
		||||
 | 
			
		||||
        if CONF_RESIZE in conf:
 | 
			
		||||
            image.thumbnail(conf[CONF_RESIZE])
 | 
			
		||||
    if CONF_RESIZE in config:
 | 
			
		||||
        image.thumbnail(config[CONF_RESIZE])
 | 
			
		||||
 | 
			
		||||
        image = image.convert('1', dither=Image.NONE)
 | 
			
		||||
        width, height = image.size
 | 
			
		||||
        if width > 500 or height > 500:
 | 
			
		||||
            _LOGGER.warning("The image you requested is very big. Please consider using the resize "
 | 
			
		||||
                            "parameter")
 | 
			
		||||
        width8 = ((width + 7) // 8) * 8
 | 
			
		||||
        data = [0 for _ in range(height * width8 // 8)]
 | 
			
		||||
        for y in range(height):
 | 
			
		||||
            for x in range(width):
 | 
			
		||||
                if image.getpixel((x, y)):
 | 
			
		||||
                    continue
 | 
			
		||||
                pos = x + y * width8
 | 
			
		||||
                data[pos // 8] |= 0x80 >> (pos % 8)
 | 
			
		||||
    image = image.convert('1', dither=Image.NONE)
 | 
			
		||||
    width, height = image.size
 | 
			
		||||
    if width > 500 or height > 500:
 | 
			
		||||
        _LOGGER.warning("The image you requested is very big. Please consider using the resize "
 | 
			
		||||
                        "parameter")
 | 
			
		||||
    width8 = ((width + 7) // 8) * 8
 | 
			
		||||
    data = [0 for _ in range(height * width8 // 8)]
 | 
			
		||||
    for y in range(height):
 | 
			
		||||
        for x in range(width):
 | 
			
		||||
            if image.getpixel((x, y)):
 | 
			
		||||
                continue
 | 
			
		||||
            pos = x + y * width8
 | 
			
		||||
            data[pos // 8] |= 0x80 >> (pos % 8)
 | 
			
		||||
 | 
			
		||||
        raw_data = MockObj(conf[CONF_RAW_DATA_ID])
 | 
			
		||||
        add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format(
 | 
			
		||||
            raw_data, len(data),
 | 
			
		||||
            ArrayInitializer(*[HexInt(x) for x in data], multiline=False))))
 | 
			
		||||
    raw_data = MockObj(config[CONF_RAW_DATA_ID])
 | 
			
		||||
    add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format(
 | 
			
		||||
        raw_data, len(data),
 | 
			
		||||
        ArrayInitializer(*[HexInt(x) for x in data], multiline=False))))
 | 
			
		||||
 | 
			
		||||
        rhs = App.make_image(raw_data, width, height)
 | 
			
		||||
        Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
    rhs = App.make_image(raw_data, width, height)
 | 
			
		||||
    Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,19 @@ import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
from esphomeyaml.components import mqtt
 | 
			
		||||
from esphomeyaml.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLORS, \
 | 
			
		||||
    CONF_COLOR_TEMPERATURE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECT, \
 | 
			
		||||
    CONF_EFFECTS, CONF_EFFECT_ID, CONF_FLASH_LENGTH, CONF_GAMMA_CORRECT, CONF_GREEN, CONF_ID, \
 | 
			
		||||
    CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, CONF_NUM_LEDS, CONF_RANDOM, CONF_RED, \
 | 
			
		||||
    CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, CONF_UPDATE_INTERVAL, CONF_WHITE, CONF_WIDTH
 | 
			
		||||
from esphomeyaml.helpers import Action, Application, ArrayInitializer, Component, Nameable, \
 | 
			
		||||
    Pvariable, StructInitializer, TemplateArguments, add, add_job, esphomelib_ns, float_, \
 | 
			
		||||
    get_variable, process_lambda, setup_mqtt_component, std_string, templatable, uint32
 | 
			
		||||
    CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECTS, CONF_EFFECT_ID, \
 | 
			
		||||
    CONF_GAMMA_CORRECT, CONF_GREEN, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, \
 | 
			
		||||
    CONF_NUM_LEDS, CONF_RANDOM, CONF_RED, CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL, CONF_WHITE, CONF_WIDTH, CONF_FLASH_LENGTH, CONF_COLOR_TEMPERATURE, \
 | 
			
		||||
    CONF_EFFECT
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import process_lambda, Pvariable, add, StructInitializer, \
 | 
			
		||||
    ArrayInitializer, get_variable, templatable
 | 
			
		||||
from esphomeyaml.cpp_types import esphomelib_ns, Application, Component, Nameable, Action, uint32, \
 | 
			
		||||
    float_, std_string
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
@@ -173,26 +177,35 @@ EFFECTS_SCHEMA = vol.Schema({
 | 
			
		||||
 | 
			
		||||
def validate_effects(allowed_effects):
 | 
			
		||||
    def validator(value):
 | 
			
		||||
        is_list = isinstance(value, list)
 | 
			
		||||
        value = cv.ensure_list(value)
 | 
			
		||||
        names = set()
 | 
			
		||||
        ret = []
 | 
			
		||||
        for i, effect in enumerate(value):
 | 
			
		||||
            path = [i] if is_list else []
 | 
			
		||||
            if not isinstance(effect, dict):
 | 
			
		||||
                raise vol.Invalid("Each effect must be a dictionary, not {}".format(type(value)))
 | 
			
		||||
                raise vol.Invalid("Each effect must be a dictionary, not {}".format(type(value)),
 | 
			
		||||
                                  path)
 | 
			
		||||
            if len(effect) > 1:
 | 
			
		||||
                raise vol.Invalid("Each entry in the 'effects:' option must be a single effect.")
 | 
			
		||||
                raise vol.Invalid("Each entry in the 'effects:' option must be a single effect.",
 | 
			
		||||
                                  path)
 | 
			
		||||
            if not effect:
 | 
			
		||||
                raise vol.Invalid("Found no effect for the {}th entry in 'effects:'!".format(i))
 | 
			
		||||
                raise vol.Invalid("Found no effect for the {}th entry in 'effects:'!".format(i),
 | 
			
		||||
                                  path)
 | 
			
		||||
            key = next(iter(effect.keys()))
 | 
			
		||||
            if key not in allowed_effects:
 | 
			
		||||
                raise vol.Invalid("The effect '{}' does not exist or is not allowed for this "
 | 
			
		||||
                                  "light type".format(key))
 | 
			
		||||
                                  "light type".format(key), path)
 | 
			
		||||
            effect[key] = effect[key] or {}
 | 
			
		||||
            conf = EFFECTS_SCHEMA(effect)
 | 
			
		||||
            try:
 | 
			
		||||
                conf = EFFECTS_SCHEMA(effect)
 | 
			
		||||
            except vol.Invalid as err:
 | 
			
		||||
                err.prepend(path)
 | 
			
		||||
                raise err
 | 
			
		||||
            name = conf[key][CONF_NAME]
 | 
			
		||||
            if name in names:
 | 
			
		||||
                raise vol.Invalid(u"Found the effect name '{}' twice. All effects must have "
 | 
			
		||||
                                  u"unique names".format(name))
 | 
			
		||||
                                  u"unique names".format(name), [i])
 | 
			
		||||
            names.add(name)
 | 
			
		||||
            ret.append(conf)
 | 
			
		||||
        return ret
 | 
			
		||||
@@ -346,7 +359,7 @@ def setup_light_core_(light_var, mqtt_var, config):
 | 
			
		||||
def setup_light(light_obj, mqtt_obj, config):
 | 
			
		||||
    light_var = Pvariable(config[CONF_ID], light_obj, has_side_effects=False)
 | 
			
		||||
    mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False)
 | 
			
		||||
    add_job(setup_light_core_, light_var, mqtt_var, config)
 | 
			
		||||
    CORE.add_job(setup_light_core_, light_var, mqtt_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_LIGHT'
 | 
			
		||||
@@ -359,8 +372,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def light_toggle_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_toggle_action(template_arg)
 | 
			
		||||
@@ -381,8 +393,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def light_turn_off_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_off_action(template_arg)
 | 
			
		||||
@@ -413,8 +424,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def light_turn_on_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_on_action(template_arg)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,9 @@ import voluptuous as vol
 | 
			
		||||
from esphomeyaml.components import light, output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_EFFECTS, CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT
 | 
			
		||||
from esphomeyaml.helpers import App, get_variable, setup_component, variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,9 @@ from esphomeyaml.components.light.rgbww import validate_cold_white_colder, \
 | 
			
		||||
from esphomeyaml.const import CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \
 | 
			
		||||
    CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \
 | 
			
		||||
    CONF_NAME, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE
 | 
			
		||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,15 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import light
 | 
			
		||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
 | 
			
		||||
from esphomeyaml.const import CONF_CHIPSET, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
 | 
			
		||||
    CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, \
 | 
			
		||||
    CONF_RGB_ORDER, CONF_EFFECTS, CONF_COLOR_CORRECT
 | 
			
		||||
from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
 | 
			
		||||
    get_variable, variable, setup_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CHIPSET, CONF_COLOR_CORRECT, CONF_DEFAULT_TRANSITION_LENGTH, \
 | 
			
		||||
    CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, \
 | 
			
		||||
    CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, CONF_RGB_ORDER
 | 
			
		||||
from esphomeyaml.cpp_generator import RawExpression, TemplateArguments, add, get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Application
 | 
			
		||||
 | 
			
		||||
TYPES = [
 | 
			
		||||
    'NEOPIXEL',
 | 
			
		||||
@@ -103,6 +104,8 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,15 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import light
 | 
			
		||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
 | 
			
		||||
from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, \
 | 
			
		||||
    CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, \
 | 
			
		||||
    CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER, CONF_EFFECTS, CONF_COLOR_CORRECT
 | 
			
		||||
from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
 | 
			
		||||
    get_variable, variable, setup_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_COLOR_CORRECT, CONF_DATA_PIN, \
 | 
			
		||||
    CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \
 | 
			
		||||
    CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER
 | 
			
		||||
from esphomeyaml.cpp_generator import RawExpression, TemplateArguments, add, get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Application
 | 
			
		||||
 | 
			
		||||
CHIPSETS = [
 | 
			
		||||
    'LPD8806',
 | 
			
		||||
@@ -83,6 +84,8 @@ def to_code(config):
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,9 @@ from esphomeyaml.components import light, output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, \
 | 
			
		||||
    CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT
 | 
			
		||||
from esphomeyaml.helpers import App, get_variable, setup_component, variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import light, output
 | 
			
		||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
 | 
			
		||||
    CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_EFFECTS
 | 
			
		||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, \
 | 
			
		||||
    CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import light, output
 | 
			
		||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
 | 
			
		||||
    CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE, CONF_EFFECTS
 | 
			
		||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, \
 | 
			
		||||
    CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import light, output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_BLUE, CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \
 | 
			
		||||
    CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, \
 | 
			
		||||
    CONF_NAME, CONF_RED, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE
 | 
			
		||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_color_temperature(value):
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,9 @@ from esphomeyaml.automation import ACTION_REGISTRY, LambdaAction
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ARGS, CONF_BAUD_RATE, CONF_FORMAT, CONF_ID, CONF_LEVEL, \
 | 
			
		||||
    CONF_LOGS, CONF_TAG, CONF_TX_BUFFER_SIZE
 | 
			
		||||
from esphomeyaml.core import ESPHomeYAMLError, Lambda
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, RawExpression, TemplateArguments, add, \
 | 
			
		||||
    esphomelib_ns, global_ns, process_lambda, statement, Component
 | 
			
		||||
from esphomeyaml.core import EsphomeyamlError, Lambda
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, RawExpression, add, process_lambda, statement
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns, global_ns
 | 
			
		||||
 | 
			
		||||
LOG_LEVELS = {
 | 
			
		||||
    'NONE': global_ns.ESPHOMELIB_LOG_LEVEL_NONE,
 | 
			
		||||
@@ -39,7 +39,7 @@ def validate_local_no_higher_than_global(value):
 | 
			
		||||
    global_level = value.get(CONF_LEVEL, 'DEBUG')
 | 
			
		||||
    for tag, level in value.get(CONF_LOGS, {}).iteritems():
 | 
			
		||||
        if LOG_LEVEL_SEVERITY.index(level) > LOG_LEVEL_SEVERITY.index(global_level):
 | 
			
		||||
            raise ESPHomeYAMLError(u"The local log level {} for {} must be less severe than the "
 | 
			
		||||
            raise EsphomeyamlError(u"The local log level {} for {} must be less severe than the "
 | 
			
		||||
                                   u"global log level {}.".format(level, tag, global_level))
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
@@ -115,8 +115,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def logger_log_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    esp_log = LOG_LEVEL_TO_ESP_LOG[config[CONF_LEVEL]]
 | 
			
		||||
    args = [RawExpression(unicode(x)) for x in config[CONF_ARGS]]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,17 +7,18 @@ from esphomeyaml import automation
 | 
			
		||||
from esphomeyaml.automation import ACTION_REGISTRY
 | 
			
		||||
from esphomeyaml.components import logger
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \
 | 
			
		||||
    CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LEVEL, \
 | 
			
		||||
    CONF_LOG_TOPIC, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, \
 | 
			
		||||
    CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_TOPIC, \
 | 
			
		||||
    CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_ON_JSON_MESSAGE, \
 | 
			
		||||
    CONF_STATE_TOPIC, CONF_MQTT, CONF_ESPHOMEYAML, CONF_NAME, CONF_AVAILABILITY, \
 | 
			
		||||
    CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_INTERNAL
 | 
			
		||||
from esphomeyaml.core import ESPHomeYAMLError
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \
 | 
			
		||||
    StructInitializer, TemplateArguments, add, esphomelib_ns, optional, std_string, templatable, \
 | 
			
		||||
    uint8, bool_, JsonObjectRef, process_lambda, JsonObjectConstRef, Component, Action, Trigger
 | 
			
		||||
from esphomeyaml.const import CONF_AVAILABILITY, CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, \
 | 
			
		||||
    CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, \
 | 
			
		||||
    CONF_ESPHOMEYAML, 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 esphomeyaml.core import EsphomeyamlError
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, RawExpression, \
 | 
			
		||||
    StructInitializer, TemplateArguments, add, process_lambda, templatable
 | 
			
		||||
from esphomeyaml.cpp_types import Action, App, Component, JsonObjectConstRef, JsonObjectRef, \
 | 
			
		||||
    Trigger, bool_, esphomelib_ns, optional, std_string, uint8
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_message_just_topic(value):
 | 
			
		||||
@@ -48,12 +49,14 @@ MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger',
 | 
			
		||||
MQTTComponent = mqtt_ns.class_('MQTTComponent', Component)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_broker(value):
 | 
			
		||||
    value = cv.string_strict(value)
 | 
			
		||||
    if u':' in value:
 | 
			
		||||
        raise vol.Invalid(u"Please specify the port using the port: option")
 | 
			
		||||
    if not value:
 | 
			
		||||
        raise vol.Invalid(u"Broker cannot be empty")
 | 
			
		||||
def validate_config(value):
 | 
			
		||||
    if CONF_PORT not in value:
 | 
			
		||||
        parts = value[CONF_BROKER].split(u':')
 | 
			
		||||
        if len(parts) == 2:
 | 
			
		||||
            value[CONF_BROKER] = parts[0]
 | 
			
		||||
            value[CONF_PORT] = cv.port(parts[1])
 | 
			
		||||
        else:
 | 
			
		||||
            value[CONF_PORT] = 1883
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -64,10 +67,10 @@ def validate_fingerprint(value):
 | 
			
		||||
    return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.All(vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(MQTTClientComponent),
 | 
			
		||||
    vol.Required(CONF_BROKER): validate_broker,
 | 
			
		||||
    vol.Optional(CONF_PORT, default=1883): cv.port,
 | 
			
		||||
    vol.Required(CONF_BROKER): cv.string_strict,
 | 
			
		||||
    vol.Optional(CONF_PORT): cv.port,
 | 
			
		||||
    vol.Optional(CONF_USERNAME, default=''): cv.string,
 | 
			
		||||
    vol.Optional(CONF_PASSWORD, default=''): cv.string,
 | 
			
		||||
    vol.Optional(CONF_CLIENT_ID): vol.All(cv.string, vol.Length(max=23)),
 | 
			
		||||
@@ -88,14 +91,15 @@ CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ON_MESSAGE): automation.validate_automation({
 | 
			
		||||
        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger),
 | 
			
		||||
        vol.Required(CONF_TOPIC): cv.subscribe_topic,
 | 
			
		||||
        vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
 | 
			
		||||
        vol.Optional(CONF_QOS): cv.mqtt_qos,
 | 
			
		||||
        vol.Optional(CONF_PAYLOAD): cv.string_strict,
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ON_JSON_MESSAGE): automation.validate_automation({
 | 
			
		||||
        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTJsonMessageTrigger),
 | 
			
		||||
        vol.Required(CONF_TOPIC): cv.subscribe_topic,
 | 
			
		||||
        vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
 | 
			
		||||
    }),
 | 
			
		||||
})
 | 
			
		||||
}), validate_config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def exp_mqtt_message(config):
 | 
			
		||||
@@ -169,8 +173,12 @@ def to_code(config):
 | 
			
		||||
        add(mqtt.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_MESSAGE, []):
 | 
			
		||||
        rhs = mqtt.make_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS])
 | 
			
		||||
        rhs = mqtt.make_message_trigger(conf[CONF_TOPIC])
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        if CONF_QOS in conf:
 | 
			
		||||
            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)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_JSON_MESSAGE, []):
 | 
			
		||||
@@ -189,8 +197,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def mqtt_publish_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg)
 | 
			
		||||
    type = MQTTPublishAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
@@ -222,8 +229,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def mqtt_publish_json_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    rhs = App.Pget_mqtt_client().Pmake_publish_json_action(template_arg)
 | 
			
		||||
    type = MQTTPublishJsonAction.template(template_arg)
 | 
			
		||||
    action = Pvariable(action_id, rhs, type=type)
 | 
			
		||||
@@ -282,7 +288,7 @@ def build_hass_config(data, component_type, config, include_state=True, include_
 | 
			
		||||
class GenerateHassConfigData(object):
 | 
			
		||||
    def __init__(self, config):
 | 
			
		||||
        if 'mqtt' not in config:
 | 
			
		||||
            raise ESPHomeYAMLError("Cannot generate Home Assistant MQTT config if MQTT is not "
 | 
			
		||||
            raise EsphomeyamlError("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_ESPHOMEYAML][CONF_NAME])
 | 
			
		||||
@@ -308,3 +314,21 @@ class GenerateHassConfigData(object):
 | 
			
		||||
                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]))
 | 
			
		||||
    if not config.get(CONF_DISCOVERY, True):
 | 
			
		||||
        add(obj.disable_discovery())
 | 
			
		||||
    if CONF_STATE_TOPIC in config:
 | 
			
		||||
        add(obj.set_custom_state_topic(config[CONF_STATE_TOPIC]))
 | 
			
		||||
    if CONF_COMMAND_TOPIC in config:
 | 
			
		||||
        add(obj.set_custom_command_topic(config[CONF_COMMAND_TOPIC]))
 | 
			
		||||
    if CONF_AVAILABILITY in config:
 | 
			
		||||
        availability = config[CONF_AVAILABILITY]
 | 
			
		||||
        if not availability:
 | 
			
		||||
            add(obj.disable_availability())
 | 
			
		||||
        else:
 | 
			
		||||
            add(obj.set_availability(availability[CONF_TOPIC], availability[CONF_PAYLOAD_AVAILABLE],
 | 
			
		||||
                                     availability[CONF_PAYLOAD_NOT_AVAILABLE]))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,18 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
from esphomeyaml.const import (CONF_DATA_PIN, CONF_CLOCK_PIN, CONF_NUM_CHANNELS,
 | 
			
		||||
                               CONF_NUM_CHIPS, CONF_BIT_DEPTH, CONF_ID,
 | 
			
		||||
                               CONF_UPDATE_ON_BOOT)
 | 
			
		||||
from esphomeyaml.helpers import (gpio_output_pin_expression, App, Pvariable,
 | 
			
		||||
                                 add, setup_component, Component)
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import (CONF_BIT_DEPTH, CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_ID,
 | 
			
		||||
                               CONF_NUM_CHANNELS, CONF_NUM_CHIPS, CONF_UPDATE_ON_BOOT)
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
MY9231OutputComponent = output.output_ns.class_('MY9231OutputComponent', Component)
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MY9231_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.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,
 | 
			
		||||
@@ -24,28 +24,23 @@ MY9231_SCHEMA = vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_UPDATE_ON_BOOT): vol.Coerce(bool),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [MY9231_SCHEMA])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        di = None
 | 
			
		||||
        for di in gpio_output_pin_expression(conf[CONF_DATA_PIN]):
 | 
			
		||||
            yield
 | 
			
		||||
        dcki = None
 | 
			
		||||
        for dcki in gpio_output_pin_expression(conf[CONF_CLOCK_PIN]):
 | 
			
		||||
            yield
 | 
			
		||||
        rhs = App.make_my9231_component(di, dcki)
 | 
			
		||||
        my9231 = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        if CONF_NUM_CHANNELS in conf:
 | 
			
		||||
            add(my9231.set_num_channels(conf[CONF_NUM_CHANNELS]))
 | 
			
		||||
        if CONF_NUM_CHIPS in conf:
 | 
			
		||||
            add(my9231.set_num_chips(conf[CONF_NUM_CHIPS]))
 | 
			
		||||
        if CONF_BIT_DEPTH in conf:
 | 
			
		||||
            add(my9231.set_bit_depth(conf[CONF_BIT_DEPTH]))
 | 
			
		||||
        if CONF_UPDATE_ON_BOOT in conf:
 | 
			
		||||
            add(my9231.set_update(conf[CONF_UPDATE_ON_BOOT]))
 | 
			
		||||
        setup_component(my9231, conf)
 | 
			
		||||
    for di in gpio_output_pin_expression(config[CONF_DATA_PIN]):
 | 
			
		||||
        yield
 | 
			
		||||
    for dcki in gpio_output_pin_expression(config[CONF_CLOCK_PIN]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = App.make_my9231_component(di, dcki)
 | 
			
		||||
    my9231 = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    if CONF_NUM_CHANNELS in config:
 | 
			
		||||
        add(my9231.set_num_channels(config[CONF_NUM_CHANNELS]))
 | 
			
		||||
    if CONF_NUM_CHIPS in config:
 | 
			
		||||
        add(my9231.set_num_chips(config[CONF_NUM_CHIPS]))
 | 
			
		||||
    if CONF_BIT_DEPTH in config:
 | 
			
		||||
        add(my9231.set_bit_depth(config[CONF_BIT_DEPTH]))
 | 
			
		||||
    if CONF_UPDATE_ON_BOOT in config:
 | 
			
		||||
        add(my9231.set_update(config[CONF_UPDATE_ON_BOOT]))
 | 
			
		||||
    setup_component(my9231, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_MY9231_OUTPUT'
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,11 @@ import logging
 | 
			
		||||
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import core
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \
 | 
			
		||||
    ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
 | 
			
		||||
from esphomeyaml.core import ESPHomeYAMLError
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, Component
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
_LOGGER = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
@@ -35,11 +34,11 @@ def to_code(config):
 | 
			
		||||
def get_port(config):
 | 
			
		||||
    if CONF_PORT in config[CONF_OTA]:
 | 
			
		||||
        return config[CONF_OTA][CONF_PORT]
 | 
			
		||||
    if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
 | 
			
		||||
    if CORE.is_esp32:
 | 
			
		||||
        return 3232
 | 
			
		||||
    elif core.ESP_PLATFORM == ESP_PLATFORM_ESP8266:
 | 
			
		||||
    elif CORE.is_esp8266:
 | 
			
		||||
        return 8266
 | 
			
		||||
    raise ESPHomeYAMLError(u"Invalid ESP Platform for ESP OTA port.")
 | 
			
		||||
    raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_auth(config):
 | 
			
		||||
@@ -51,6 +50,8 @@ REQUIRED_BUILD_FLAGS = '-DUSE_NEW_OTA'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def lib_deps(config):
 | 
			
		||||
    if core.ESP_PLATFORM == ESP_PLATFORM_ESP32:
 | 
			
		||||
        return ['ArduinoOTA', 'Update', 'ESPmDNS']
 | 
			
		||||
    return ['Hash', 'ESP8266mDNS', 'ArduinoOTA']
 | 
			
		||||
    if CORE.is_esp32:
 | 
			
		||||
        return ['Update', 'ESPmDNS']
 | 
			
		||||
    elif CORE.is_esp8266:
 | 
			
		||||
        return ['Hash', 'ESP8266mDNS']
 | 
			
		||||
    raise NotImplementedError
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,9 @@ from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
 | 
			
		||||
from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY, CONF_ID, CONF_LEVEL
 | 
			
		||||
from esphomeyaml.helpers import add, esphomelib_ns, get_variable, TemplateArguments, Pvariable, \
 | 
			
		||||
    templatable, float_, add_job, Action
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import add, get_variable, Pvariable, templatable
 | 
			
		||||
from esphomeyaml.cpp_types import esphomelib_ns, Action, float_
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +27,9 @@ FLOAT_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FLOAT_OUTPUT_SCHEMA.schema
 | 
			
		||||
 | 
			
		||||
output_ns = esphomelib_ns.namespace('output')
 | 
			
		||||
BinaryOutput = output_ns.class_('BinaryOutput')
 | 
			
		||||
BinaryOutputPtr = BinaryOutput.operator('ptr')
 | 
			
		||||
FloatOutput = output_ns.class_('FloatOutput', BinaryOutput)
 | 
			
		||||
FloatOutputPtr = FloatOutput.operator('ptr')
 | 
			
		||||
 | 
			
		||||
# Actions
 | 
			
		||||
TurnOffAction = output_ns.class_('TurnOffAction', Action)
 | 
			
		||||
@@ -47,7 +50,12 @@ def setup_output_platform_(obj, config, skip_power_supply=False):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def setup_output_platform(obj, config, skip_power_supply=False):
 | 
			
		||||
    add_job(setup_output_platform_, obj, config, skip_power_supply)
 | 
			
		||||
    CORE.add_job(setup_output_platform_, obj, config, skip_power_supply)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_output(var, config):
 | 
			
		||||
    output_var = Pvariable(config[CONF_ID], var, has_side_effects=True)
 | 
			
		||||
    CORE.add_job(setup_output_platform_, output_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_OUTPUT'
 | 
			
		||||
@@ -60,8 +68,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def output_turn_on_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_on_action(template_arg)
 | 
			
		||||
@@ -76,8 +83,7 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def output_turn_off_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_turn_off_action(template_arg)
 | 
			
		||||
@@ -93,8 +99,7 @@ OUTPUT_SET_LEVEL_ACTION = vol.Schema({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_OUTPUT_SET_LEVEL, OUTPUT_SET_LEVEL_ACTION)
 | 
			
		||||
def output_set_level_to_code(config, action_id, arg_type):
 | 
			
		||||
    template_arg = TemplateArguments(arg_type)
 | 
			
		||||
def output_set_level_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_set_level_action(template_arg)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								esphomeyaml/components/output/custom.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								esphomeyaml/components/output/custom.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE
 | 
			
		||||
from esphomeyaml.cpp_generator import process_lambda, variable
 | 
			
		||||
from esphomeyaml.cpp_types import std_vector
 | 
			
		||||
 | 
			
		||||
CustomBinaryOutputConstructor = output.output_ns.class_('CustomBinaryOutputConstructor')
 | 
			
		||||
CustomFloatOutputConstructor = output.output_ns.class_('CustomFloatOutputConstructor')
 | 
			
		||||
 | 
			
		||||
BINARY_SCHEMA = output.PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(CustomBinaryOutputConstructor),
 | 
			
		||||
    vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Required(CONF_OUTPUTS):
 | 
			
		||||
        vol.All(cv.ensure_list, [output.BINARY_OUTPUT_SCHEMA.extend({
 | 
			
		||||
            cv.GenerateID(): cv.declare_variable_id(output.BinaryOutput),
 | 
			
		||||
        })]),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
FLOAT_SCHEMA = output.PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(CustomFloatOutputConstructor),
 | 
			
		||||
    vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Required(CONF_OUTPUTS):
 | 
			
		||||
        vol.All(cv.ensure_list, [output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({
 | 
			
		||||
            cv.GenerateID(): cv.declare_variable_id(output.FloatOutput),
 | 
			
		||||
        })]),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_custom_output(value):
 | 
			
		||||
    if not isinstance(value, dict):
 | 
			
		||||
        raise vol.Invalid("Value must be dict")
 | 
			
		||||
    if CONF_TYPE not in value:
 | 
			
		||||
        raise vol.Invalid("type not specified!")
 | 
			
		||||
    type = cv.string_strict(value[CONF_TYPE]).lower()
 | 
			
		||||
    value[CONF_TYPE] = type
 | 
			
		||||
    if type == 'binary':
 | 
			
		||||
        return BINARY_SCHEMA(value)
 | 
			
		||||
    elif type == 'float':
 | 
			
		||||
        return FLOAT_SCHEMA(value)
 | 
			
		||||
    raise vol.Invalid("type must either be binary or float, not {}!".format(type))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = validate_custom_output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    type = config[CONF_TYPE]
 | 
			
		||||
    if type == 'binary':
 | 
			
		||||
        ret_type = output.BinaryOutputPtr
 | 
			
		||||
        klass = CustomBinaryOutputConstructor
 | 
			
		||||
    else:
 | 
			
		||||
        ret_type = output.FloatOutputPtr
 | 
			
		||||
        klass = CustomFloatOutputConstructor
 | 
			
		||||
    for template_ in process_lambda(config[CONF_LAMBDA], [],
 | 
			
		||||
                                    return_type=std_vector.template(ret_type)):
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
    rhs = klass(template_)
 | 
			
		||||
    custom = variable(config[CONF_ID], rhs)
 | 
			
		||||
    for i, sens in enumerate(config[CONF_OUTPUTS]):
 | 
			
		||||
        output.register_output(custom.get_output(i), sens)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_CUSTOM_OUTPUT'
 | 
			
		||||
@@ -3,9 +3,10 @@ import voluptuous as vol
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266, CONF_FREQUENCY
 | 
			
		||||
from esphomeyaml.helpers import App, Component, Pvariable, gpio_output_pin_expression, \
 | 
			
		||||
    setup_component, add
 | 
			
		||||
from esphomeyaml.const import CONF_FREQUENCY, CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP8266]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_PIN
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression, setup_component, \
 | 
			
		||||
    Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
GPIOBinaryOutputComponent = output.output_ns.class_('GPIOBinaryOutputComponent',
 | 
			
		||||
                                                    output.BinaryOutput, Component)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import APB_CLOCK_FREQ, CONF_BIT_DEPTH, CONF_CHANNEL, CONF_FREQUENCY, \
 | 
			
		||||
    CONF_ID, CONF_PIN, ESP_PLATFORM_ESP32
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,11 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
from esphomeyaml.components.my9231 import MY9231OutputComponent
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_MY9231_ID, CONF_POWER_SUPPLY
 | 
			
		||||
from esphomeyaml.helpers import Pvariable, get_variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['my9231']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import output
 | 
			
		||||
from esphomeyaml.components.pca9685 import PCA9685OutputComponent
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_PCA9685_ID, CONF_POWER_SUPPLY
 | 
			
		||||
from esphomeyaml.helpers import Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['pca9685']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,37 +1,32 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.components import i2c, output
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import output, i2c
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_FREQUENCY, CONF_ID, CONF_PHASE_BALANCER
 | 
			
		||||
from esphomeyaml.helpers import App, HexIntLiteral, Pvariable, add, setup_component, Component
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_FREQUENCY, CONF_ID
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
PCA9685OutputComponent = output.output_ns.class_('PCA9685OutputComponent',
 | 
			
		||||
                                                 Component, i2c.I2CDevice)
 | 
			
		||||
 | 
			
		||||
PHASE_BALANCER_MESSAGE = ("The phase_balancer option has been removed in version 1.5.0. "
 | 
			
		||||
                          "esphomelib will now automatically choose a suitable phase balancer.")
 | 
			
		||||
 | 
			
		||||
PCA9685_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(PCA9685OutputComponent),
 | 
			
		||||
    vol.Required(CONF_FREQUENCY): vol.All(cv.frequency,
 | 
			
		||||
                                          vol.Range(min=23.84, max=1525.88)),
 | 
			
		||||
    vol.Optional(CONF_ADDRESS): cv.i2c_address,
 | 
			
		||||
 | 
			
		||||
    vol.Optional(CONF_PHASE_BALANCER): cv.invalid(PHASE_BALANCER_MESSAGE),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCA9685_SCHEMA])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        rhs = App.make_pca9685_component(conf.get(CONF_FREQUENCY))
 | 
			
		||||
        pca9685 = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        if CONF_ADDRESS in conf:
 | 
			
		||||
            add(pca9685.set_address(HexIntLiteral(conf[CONF_ADDRESS])))
 | 
			
		||||
        setup_component(pca9685, conf)
 | 
			
		||||
    rhs = App.make_pca9685_component(config.get(CONF_FREQUENCY))
 | 
			
		||||
    pca9685 = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    if CONF_ADDRESS in config:
 | 
			
		||||
        add(pca9685.set_address(config[CONF_ADDRESS]))
 | 
			
		||||
    setup_component(pca9685, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT'
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,12 @@ import voluptuous as vol
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575
 | 
			
		||||
from esphomeyaml.helpers import App, GPIOInputPin, GPIOOutputPin, Pvariable, io_ns, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, GPIOInputPin, GPIOOutputPin, io_ns
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
PCF8574GPIOMode = io_ns.enum('PCF8574GPIOMode')
 | 
			
		||||
PCF8675_GPIO_MODES = {
 | 
			
		||||
@@ -17,20 +20,17 @@ PCF8675_GPIO_MODES = {
 | 
			
		||||
PCF8574GPIOInputPin = io_ns.class_('PCF8574GPIOInputPin', GPIOInputPin)
 | 
			
		||||
PCF8574GPIOOutputPin = io_ns.class_('PCF8574GPIOOutputPin', GPIOOutputPin)
 | 
			
		||||
 | 
			
		||||
PCF8574_SCHEMA = vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.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,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575])
 | 
			
		||||
        var = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        setup_component(var, conf)
 | 
			
		||||
    rhs = App.make_pcf8574_component(config[CONF_ADDRESS], config[CONF_PCF8575])
 | 
			
		||||
    var = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    setup_component(var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_PCF8574'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,23 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins, automation
 | 
			
		||||
from esphomeyaml import automation, pins
 | 
			
		||||
from esphomeyaml.components import binary_sensor, spi
 | 
			
		||||
from esphomeyaml.components.spi import SPIComponent
 | 
			
		||||
from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL, \
 | 
			
		||||
    CONF_ON_TAG, CONF_TRIGGER_ID
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, get_variable, gpio_output_pin_expression, \
 | 
			
		||||
    std_string, setup_component, PollingComponent, Trigger
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_ON_TAG, CONF_SPI_ID, CONF_TRIGGER_ID, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent, Trigger, std_string
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['spi']
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
PN532Component = binary_sensor.binary_sensor_ns.class_('PN532Component', PollingComponent,
 | 
			
		||||
                                                       spi.SPIDevice)
 | 
			
		||||
PN532Trigger = binary_sensor.binary_sensor_ns.class_('PN532Trigger', Trigger.template(std_string))
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.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,
 | 
			
		||||
@@ -23,23 +25,22 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_ON_TAG): automation.validate_automation({
 | 
			
		||||
        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PN532Trigger),
 | 
			
		||||
    }),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for spi_ in get_variable(conf[CONF_SPI_ID]):
 | 
			
		||||
            yield
 | 
			
		||||
        for cs in gpio_output_pin_expression(conf[CONF_CS_PIN]):
 | 
			
		||||
            yield
 | 
			
		||||
        rhs = App.make_pn532_component(spi_, cs, conf.get(CONF_UPDATE_INTERVAL))
 | 
			
		||||
        pn532 = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
    for spi_ in get_variable(config[CONF_SPI_ID]):
 | 
			
		||||
        yield
 | 
			
		||||
    for cs in gpio_output_pin_expression(config[CONF_CS_PIN]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = App.make_pn532_component(spi_, cs, config.get(CONF_UPDATE_INTERVAL))
 | 
			
		||||
    pn532 = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 | 
			
		||||
        for conf_ in conf.get(CONF_ON_TAG, []):
 | 
			
		||||
            trigger = Pvariable(conf_[CONF_TRIGGER_ID], pn532.make_trigger())
 | 
			
		||||
            automation.build_automation(trigger, std_string, conf_)
 | 
			
		||||
    for conf_ in config.get(CONF_ON_TAG, []):
 | 
			
		||||
        trigger = Pvariable(conf_[CONF_TRIGGER_ID], pn532.make_trigger())
 | 
			
		||||
        automation.build_automation(trigger, std_string, conf_)
 | 
			
		||||
 | 
			
		||||
        setup_component(pn532, conf)
 | 
			
		||||
    setup_component(pn532, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_PN532'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,36 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression, \
 | 
			
		||||
    setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
PowerSupplyComponent = esphomelib_ns.class_('PowerSupplyComponent', Component)
 | 
			
		||||
 | 
			
		||||
POWER_SUPPLY_SCHEMA = vol.Schema({
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.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,
 | 
			
		||||
    vol.Optional(CONF_KEEP_ON_TIME): cv.positive_time_period_milliseconds,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for pin in gpio_output_pin_expression(conf[CONF_PIN]):
 | 
			
		||||
            yield
 | 
			
		||||
    for pin in gpio_output_pin_expression(config[CONF_PIN]):
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
        rhs = App.make_power_supply(pin)
 | 
			
		||||
        psu = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        if CONF_ENABLE_TIME in conf:
 | 
			
		||||
            add(psu.set_enable_time(conf[CONF_ENABLE_TIME]))
 | 
			
		||||
        if CONF_KEEP_ON_TIME in conf:
 | 
			
		||||
            add(psu.set_keep_on_time(conf[CONF_KEEP_ON_TIME]))
 | 
			
		||||
    rhs = App.make_power_supply(pin)
 | 
			
		||||
    psu = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    if CONF_ENABLE_TIME in config:
 | 
			
		||||
        add(psu.set_enable_time(config[CONF_ENABLE_TIME]))
 | 
			
		||||
    if CONF_KEEP_ON_TIME in config:
 | 
			
		||||
        add(psu.set_keep_on_time(config[CONF_KEEP_ON_TIME]))
 | 
			
		||||
 | 
			
		||||
        setup_component(psu, conf)
 | 
			
		||||
    setup_component(psu, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_OUTPUT'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +1,29 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import binary_sensor, uart
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_UART_ID
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, get_variable, setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['uart']
 | 
			
		||||
 | 
			
		||||
RDM6300Component = binary_sensor.binary_sensor_ns.class_('RDM6300Component', Component,
 | 
			
		||||
                                                         uart.UARTDevice)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list_not_empty, [vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(RDM6300Component),
 | 
			
		||||
    cv.GenerateID(CONF_UART_ID): cv.use_variable_id(uart.UARTComponent),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for uart_ in get_variable(conf[CONF_UART_ID]):
 | 
			
		||||
            yield
 | 
			
		||||
        rhs = App.make_rdm6300_component(uart_)
 | 
			
		||||
        var = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
        setup_component(var, conf)
 | 
			
		||||
    for uart_ in get_variable(config[CONF_UART_ID]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = App.make_rdm6300_component(uart_)
 | 
			
		||||
    var = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
    setup_component(var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_RDM6300'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,15 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_BUFFER_SIZE, CONF_DUMP, CONF_FILTER, CONF_ID, CONF_IDLE, \
 | 
			
		||||
    CONF_PIN, CONF_TOLERANCE
 | 
			
		||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_input_pin_expression, \
 | 
			
		||||
    setup_component, Component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_input_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
remote_ns = esphomelib_ns.namespace('remote')
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
RemoteControlComponentBase = remote_ns.class_('RemoteControlComponentBase')
 | 
			
		||||
RemoteReceiverComponent = remote_ns.class_('RemoteReceiverComponent',
 | 
			
		||||
@@ -35,7 +37,7 @@ def validate_dumpers_all(value):
 | 
			
		||||
    raise vol.Invalid("Not valid dumpers")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.Schema({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(RemoteReceiverComponent),
 | 
			
		||||
    vol.Required(CONF_PIN): pins.gpio_input_pin_schema,
 | 
			
		||||
    vol.Optional(CONF_DUMP, default=[]):
 | 
			
		||||
@@ -45,28 +47,27 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_BUFFER_SIZE): cv.validate_bytes,
 | 
			
		||||
    vol.Optional(CONF_FILTER): cv.positive_time_period_microseconds,
 | 
			
		||||
    vol.Optional(CONF_IDLE): cv.positive_time_period_microseconds,
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for pin in gpio_input_pin_expression(conf[CONF_PIN]):
 | 
			
		||||
            yield
 | 
			
		||||
        rhs = App.make_remote_receiver_component(pin)
 | 
			
		||||
        receiver = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
    for pin in gpio_input_pin_expression(config[CONF_PIN]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = App.make_remote_receiver_component(pin)
 | 
			
		||||
    receiver = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 | 
			
		||||
        for dumper in conf[CONF_DUMP]:
 | 
			
		||||
            add(receiver.add_dumper(DUMPERS[dumper].new()))
 | 
			
		||||
        if CONF_TOLERANCE in conf:
 | 
			
		||||
            add(receiver.set_tolerance(conf[CONF_TOLERANCE]))
 | 
			
		||||
        if CONF_BUFFER_SIZE in conf:
 | 
			
		||||
            add(receiver.set_buffer_size(conf[CONF_BUFFER_SIZE]))
 | 
			
		||||
        if CONF_FILTER in conf:
 | 
			
		||||
            add(receiver.set_filter_us(conf[CONF_FILTER]))
 | 
			
		||||
        if CONF_IDLE in conf:
 | 
			
		||||
            add(receiver.set_idle_us(conf[CONF_IDLE]))
 | 
			
		||||
    for dumper in config[CONF_DUMP]:
 | 
			
		||||
        add(receiver.add_dumper(DUMPERS[dumper].new()))
 | 
			
		||||
    if CONF_TOLERANCE in config:
 | 
			
		||||
        add(receiver.set_tolerance(config[CONF_TOLERANCE]))
 | 
			
		||||
    if CONF_BUFFER_SIZE in config:
 | 
			
		||||
        add(receiver.set_buffer_size(config[CONF_BUFFER_SIZE]))
 | 
			
		||||
    if CONF_FILTER in config:
 | 
			
		||||
        add(receiver.set_filter_us(config[CONF_FILTER]))
 | 
			
		||||
    if CONF_IDLE in config:
 | 
			
		||||
        add(receiver.set_idle_us(config[CONF_IDLE]))
 | 
			
		||||
 | 
			
		||||
        setup_component(receiver, conf)
 | 
			
		||||
    setup_component(receiver, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_REMOTE_RECEIVER'
 | 
			
		||||
 
 | 
			
		||||
@@ -7,14 +7,17 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_DUTY_PERCENT, CONF_CHAN
 | 
			
		||||
    CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_ID, CONF_INVERTED, CONF_ONE, CONF_PIN, \
 | 
			
		||||
    CONF_PROTOCOL, CONF_PULSE_LENGTH, CONF_STATE, CONF_SYNC, CONF_ZERO
 | 
			
		||||
from esphomeyaml.core import HexInt
 | 
			
		||||
from esphomeyaml.helpers import App, Component, Pvariable, add, gpio_output_pin_expression, \
 | 
			
		||||
    setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import gpio_output_pin_expression, setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component
 | 
			
		||||
 | 
			
		||||
RemoteTransmitterComponent = remote_ns.class_('RemoteTransmitterComponent',
 | 
			
		||||
                                              RemoteControlComponentBase, Component)
 | 
			
		||||
RCSwitchProtocol = remote_ns.class_('RCSwitchProtocol')
 | 
			
		||||
rc_switch_protocols = remote_ns.rc_switch_protocols
 | 
			
		||||
 | 
			
		||||
MULTI_CONF = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_rc_switch_code(value):
 | 
			
		||||
    if not isinstance(value, (str, unicode)):
 | 
			
		||||
@@ -75,12 +78,12 @@ RC_SWITCH_TYPE_D_SCHEMA = vol.Schema({
 | 
			
		||||
    vol.Optional(CONF_PROTOCOL, default=1): RC_SWITCH_PROTOCOL_SCHEMA,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
 | 
			
		||||
CONFIG_SCHEMA = vol.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,
 | 
			
		||||
                                                     vol.Range(min=1, max=100)),
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
 | 
			
		||||
}).extend(cv.COMPONENT_SCHEMA.schema)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_rc_switch_protocol(config):
 | 
			
		||||
@@ -102,16 +105,15 @@ def binary_code(value):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for conf in config:
 | 
			
		||||
        for pin in gpio_output_pin_expression(conf[CONF_PIN]):
 | 
			
		||||
            yield
 | 
			
		||||
        rhs = App.make_remote_transmitter_component(pin)
 | 
			
		||||
        transmitter = Pvariable(conf[CONF_ID], rhs)
 | 
			
		||||
    for pin in gpio_output_pin_expression(config[CONF_PIN]):
 | 
			
		||||
        yield
 | 
			
		||||
    rhs = App.make_remote_transmitter_component(pin)
 | 
			
		||||
    transmitter = Pvariable(config[CONF_ID], rhs)
 | 
			
		||||
 | 
			
		||||
        if CONF_CARRIER_DUTY_PERCENT in conf:
 | 
			
		||||
            add(transmitter.set_carrier_duty_percent(conf[CONF_CARRIER_DUTY_PERCENT]))
 | 
			
		||||
    if CONF_CARRIER_DUTY_PERCENT in config:
 | 
			
		||||
        add(transmitter.set_carrier_duty_percent(config[CONF_CARRIER_DUTY_PERCENT]))
 | 
			
		||||
 | 
			
		||||
        setup_component(transmitter, conf)
 | 
			
		||||
    setup_component(transmitter, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_REMOTE_TRANSMITTER'
 | 
			
		||||
 
 | 
			
		||||
@@ -4,11 +4,12 @@ from esphomeyaml import automation
 | 
			
		||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID
 | 
			
		||||
from esphomeyaml.helpers import NoArg, Pvariable, TemplateArguments, esphomelib_ns, get_variable, \
 | 
			
		||||
    Trigger, Action
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import Action, NoArg, Trigger, esphomelib_ns
 | 
			
		||||
 | 
			
		||||
Script = esphomelib_ns.class_('Script', Trigger.template(NoArg))
 | 
			
		||||
ScriptExecuteAction = esphomelib_ns.class_('ScriptExecuteAction', Action)
 | 
			
		||||
ScriptStopAction = esphomelib_ns.class_('ScriptStopAction', Action)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = automation.validate_automation({
 | 
			
		||||
    vol.Required(CONF_ID): cv.declare_variable_id(Script),
 | 
			
		||||
@@ -28,10 +29,24 @@ 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 = TemplateArguments(arg_type)
 | 
			
		||||
def script_execute_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_execute_action(template_arg)
 | 
			
		||||
    type = ScriptExecuteAction.template(arg_type)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_SCRIPT_STOP = 'script.stop'
 | 
			
		||||
SCRIPT_STOP_ACTION_SCHEMA = maybe_simple_id({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(Script),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ACTION_REGISTRY.register(CONF_SCRIPT_STOP, SCRIPT_STOP_ACTION_SCHEMA)
 | 
			
		||||
def script_stop_action_to_code(config, action_id, arg_type, template_arg):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_stop_action(template_arg)
 | 
			
		||||
    type = ScriptStopAction.template(arg_type)
 | 
			
		||||
    yield Pvariable(action_id, rhs, type=type)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml import automation
 | 
			
		||||
from esphomeyaml.automation import CONDITION_REGISTRY
 | 
			
		||||
from esphomeyaml.components import mqtt
 | 
			
		||||
from esphomeyaml.components.mqtt import setup_mqtt_component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
 | 
			
		||||
    CONF_DEBOUNCE, CONF_DELTA, CONF_EXPIRE_AFTER, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, \
 | 
			
		||||
@@ -10,9 +12,11 @@ from esphomeyaml.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CO
 | 
			
		||||
    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
 | 
			
		||||
from esphomeyaml.helpers import App, ArrayInitializer, Component, Nameable, PollingComponent, \
 | 
			
		||||
    Pvariable, Trigger, add, add_job, esphomelib_ns, float_, process_lambda, setup_mqtt_component, \
 | 
			
		||||
    templatable
 | 
			
		||||
from esphomeyaml.core import CORE
 | 
			
		||||
from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, add, process_lambda, \
 | 
			
		||||
    templatable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import App, Component, Nameable, PollingComponent, Trigger, \
 | 
			
		||||
    esphomelib_ns, float_
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
@@ -37,9 +41,9 @@ FILTER_KEYS = [CONF_OFFSET, CONF_MULTIPLY, CONF_FILTER_OUT, CONF_FILTER_NAN,
 | 
			
		||||
               CONF_THROTTLE, CONF_DELTA, CONF_UNIQUE, CONF_HEARTBEAT, CONF_DEBOUNCE, CONF_OR]
 | 
			
		||||
 | 
			
		||||
FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
 | 
			
		||||
    vol.Optional(CONF_OFFSET): vol.Coerce(float),
 | 
			
		||||
    vol.Optional(CONF_MULTIPLY): vol.Coerce(float),
 | 
			
		||||
    vol.Optional(CONF_FILTER_OUT): vol.Coerce(float),
 | 
			
		||||
    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.Required(CONF_WINDOW_SIZE): cv.positive_not_null_int,
 | 
			
		||||
@@ -52,7 +56,7 @@ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Optional(CONF_THROTTLE): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_DELTA): vol.Coerce(float),
 | 
			
		||||
    vol.Optional(CONF_DELTA): cv.float_,
 | 
			
		||||
    vol.Optional(CONF_UNIQUE): None,
 | 
			
		||||
    vol.Optional(CONF_HEARTBEAT): cv.positive_time_period_milliseconds,
 | 
			
		||||
    vol.Optional(CONF_DEBOUNCE): cv.positive_time_period_milliseconds,
 | 
			
		||||
@@ -62,6 +66,7 @@ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
 | 
			
		||||
# Base
 | 
			
		||||
sensor_ns = esphomelib_ns.namespace('sensor')
 | 
			
		||||
Sensor = sensor_ns.class_('Sensor', Nameable)
 | 
			
		||||
SensorPtr = Sensor.operator('ptr')
 | 
			
		||||
MQTTSensorComponent = sensor_ns.class_('MQTTSensorComponent', mqtt.MQTTComponent)
 | 
			
		||||
 | 
			
		||||
PollingSensorComponent = sensor_ns.class_('PollingSensorComponent', PollingComponent, Sensor)
 | 
			
		||||
@@ -71,7 +76,7 @@ EmptyPollingParentSensor = sensor_ns.class_('EmptyPollingParentSensor', EmptySen
 | 
			
		||||
# Triggers
 | 
			
		||||
SensorStateTrigger = sensor_ns.class_('SensorStateTrigger', Trigger.template(float_))
 | 
			
		||||
SensorRawStateTrigger = sensor_ns.class_('SensorRawStateTrigger', Trigger.template(float_))
 | 
			
		||||
ValueRangeTrigger = sensor_ns.class_('ValueRangeTrigger', Trigger.template(float_))
 | 
			
		||||
ValueRangeTrigger = sensor_ns.class_('ValueRangeTrigger', Trigger.template(float_), Component)
 | 
			
		||||
 | 
			
		||||
# Filters
 | 
			
		||||
Filter = sensor_ns.class_('Filter')
 | 
			
		||||
@@ -88,6 +93,7 @@ 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)
 | 
			
		||||
SensorInRangeCondition = sensor_ns.class_('SensorInRangeCondition', Filter)
 | 
			
		||||
 | 
			
		||||
SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTSensorComponent),
 | 
			
		||||
@@ -104,8 +110,8 @@ SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
 | 
			
		||||
    }),
 | 
			
		||||
    vol.Optional(CONF_ON_VALUE_RANGE): automation.validate_automation({
 | 
			
		||||
        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ValueRangeTrigger),
 | 
			
		||||
        vol.Optional(CONF_ABOVE): vol.Coerce(float),
 | 
			
		||||
        vol.Optional(CONF_BELOW): vol.Coerce(float),
 | 
			
		||||
        vol.Optional(CONF_ABOVE): cv.float_,
 | 
			
		||||
        vol.Optional(CONF_BELOW): cv.float_,
 | 
			
		||||
    }, cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -186,13 +192,12 @@ def setup_sensor_core_(sensor_var, mqtt_var, config):
 | 
			
		||||
    for conf in config.get(CONF_ON_VALUE_RANGE, []):
 | 
			
		||||
        rhs = sensor_var.make_value_range_trigger()
 | 
			
		||||
        trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
 | 
			
		||||
        add(App.register_component(trigger))
 | 
			
		||||
        if CONF_ABOVE in conf:
 | 
			
		||||
            template_ = None
 | 
			
		||||
            for template_ in templatable(conf[CONF_ABOVE], float_, float_):
 | 
			
		||||
                yield
 | 
			
		||||
            add(trigger.set_min(template_))
 | 
			
		||||
        if CONF_BELOW in conf:
 | 
			
		||||
            template_ = None
 | 
			
		||||
            for template_ in templatable(conf[CONF_BELOW], float_, float_):
 | 
			
		||||
                yield
 | 
			
		||||
            add(trigger.set_max(template_))
 | 
			
		||||
@@ -209,19 +214,43 @@ def setup_sensor_core_(sensor_var, mqtt_var, config):
 | 
			
		||||
def setup_sensor(sensor_obj, mqtt_obj, config):
 | 
			
		||||
    sensor_var = Pvariable(config[CONF_ID], sensor_obj, has_side_effects=False)
 | 
			
		||||
    mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False)
 | 
			
		||||
    add_job(setup_sensor_core_, sensor_var, mqtt_var, config)
 | 
			
		||||
    CORE.add_job(setup_sensor_core_, sensor_var, mqtt_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_sensor(var, config):
 | 
			
		||||
    sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True)
 | 
			
		||||
    rhs = App.register_sensor(sensor_var)
 | 
			
		||||
    mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True)
 | 
			
		||||
    add_job(setup_sensor_core_, sensor_var, mqtt_var, config)
 | 
			
		||||
    CORE.add_job(setup_sensor_core_, sensor_var, mqtt_var, config)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUILD_FLAGS = '-DUSE_SENSOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONF_SENSOR_IN_RANGE = 'sensor.in_range'
 | 
			
		||||
SENSOR_IN_RANGE_CONDITION_SCHEMA = vol.All({
 | 
			
		||||
    vol.Required(CONF_ID): cv.use_variable_id(Sensor),
 | 
			
		||||
    vol.Optional(CONF_ABOVE): cv.float_,
 | 
			
		||||
    vol.Optional(CONF_BELOW): cv.float_,
 | 
			
		||||
}, cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@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):
 | 
			
		||||
    for var in get_variable(config[CONF_ID]):
 | 
			
		||||
        yield None
 | 
			
		||||
    rhs = var.make_sensor_in_range_condition(template_arg)
 | 
			
		||||
    type = SensorInRangeCondition.template(arg_type)
 | 
			
		||||
    cond = Pvariable(condition_id, rhs, type=type)
 | 
			
		||||
 | 
			
		||||
    if CONF_ABOVE in config:
 | 
			
		||||
        add(cond.set_min(config[CONF_ABOVE]))
 | 
			
		||||
    if CONF_BELOW in config:
 | 
			
		||||
        add(cond.set_max(config[CONF_BELOW]))
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml import pins
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ATTENUATION, CONF_MAKE_ID, CONF_NAME, CONF_PIN, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import App, Application, add, global_ns, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import add, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Application, global_ns
 | 
			
		||||
 | 
			
		||||
ATTENUATION_MODES = {
 | 
			
		||||
    '0db': global_ns.ADC_0db,
 | 
			
		||||
@@ -60,3 +62,9 @@ def required_build_flags(config):
 | 
			
		||||
 | 
			
		||||
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);'
 | 
			
		||||
    return None
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
from esphomeyaml.components.ads1115 import ADS1115Component
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_NAME, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import get_variable
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['ads1115']
 | 
			
		||||
 | 
			
		||||
@@ -59,7 +59,6 @@ PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    hub = None
 | 
			
		||||
    for hub in get_variable(config[CONF_ADS1115_ID]):
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.components import i2c, sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor, i2c
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_RESOLUTION, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import add, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Application
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
 | 
			
		||||
    make_address_array
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
 | 
			
		||||
from esphomeyaml.helpers import get_variable, esphomelib_ns
 | 
			
		||||
from esphomeyaml.cpp_generator import get_variable
 | 
			
		||||
from esphomeyaml.cpp_types import esphomelib_ns
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['esp32_ble_tracker']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,9 @@ import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_IIR_FILTER, CONF_MAKE_ID, \
 | 
			
		||||
    CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ from esphomeyaml.components import sensor
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_GAS_RESISTANCE, CONF_HUMIDITY, CONF_IIR_FILTER, \
 | 
			
		||||
    CONF_MAKE_ID, CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL, CONF_HEATER, CONF_DURATION
 | 
			
		||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable, add
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,9 @@ import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_PRESSURE, \
 | 
			
		||||
    CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import App, Application, HexIntLiteral, add, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import variable, add, HexIntLiteral
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import Application, App
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ADDRESS, CONF_IIR_FILTER, CONF_MAKE_ID, \
 | 
			
		||||
    CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
 | 
			
		||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import add, variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, Application
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['i2c']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,9 @@ from esphomeyaml.components.uart import UARTComponent
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_CURRENT, CONF_ID, CONF_NAME, CONF_POWER, CONF_UART_ID, \
 | 
			
		||||
    CONF_UPDATE_INTERVAL, CONF_VOLTAGE
 | 
			
		||||
from esphomeyaml.helpers import App, PollingComponent, Pvariable, get_variable, setup_component
 | 
			
		||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
 | 
			
		||||
from esphomeyaml.cpp_helpers import setup_component
 | 
			
		||||
from esphomeyaml.cpp_types import App, PollingComponent
 | 
			
		||||
 | 
			
		||||
DEPENDENCIES = ['uart']
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								esphomeyaml/components/sensor/custom.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								esphomeyaml/components/sensor/custom.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
import voluptuous as vol
 | 
			
		||||
 | 
			
		||||
from esphomeyaml.components import sensor
 | 
			
		||||
import esphomeyaml.config_validation as cv
 | 
			
		||||
from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_SENSORS
 | 
			
		||||
from esphomeyaml.cpp_generator import process_lambda, variable
 | 
			
		||||
from esphomeyaml.cpp_types import std_vector
 | 
			
		||||
 | 
			
		||||
CustomSensorConstructor = sensor.sensor_ns.class_('CustomSensorConstructor')
 | 
			
		||||
 | 
			
		||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
 | 
			
		||||
    cv.GenerateID(): cv.declare_variable_id(CustomSensorConstructor),
 | 
			
		||||
    vol.Required(CONF_LAMBDA): cv.lambda_,
 | 
			
		||||
    vol.Required(CONF_SENSORS): vol.All(cv.ensure_list, [sensor.SENSOR_SCHEMA.extend({
 | 
			
		||||
        cv.GenerateID(): cv.declare_variable_id(sensor.Sensor),
 | 
			
		||||
    })]),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def to_code(config):
 | 
			
		||||
    for template_ in process_lambda(config[CONF_LAMBDA], [],
 | 
			
		||||
                                    return_type=std_vector.template(sensor.SensorPtr)):
 | 
			
		||||
        yield
 | 
			
		||||
 | 
			
		||||
    rhs = CustomSensorConstructor(template_)
 | 
			
		||||
    custom = variable(config[CONF_ID], rhs)
 | 
			
		||||
    for i, sens in enumerate(config[CONF_SENSORS]):
 | 
			
		||||
        sensor.register_sensor(custom.get_sensor(i), sens)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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]]
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user