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

Compare commits

..

52 Commits

Author SHA1 Message Date
Otto Winter
b71b14cd06 Bump HassIO version to v1.10.1 2019-01-13 19:06:09 +01:00
Otto Winter
145e7b00ee Bump version to v1.10.1 2019-01-13 19:04:57 +01:00
Otto Winter
07c80dfcda Pin platformio platforms (#335) 2019-01-13 19:04:54 +01:00
Otto Winter
0e52c9a778 Introduce wifi fast connect mode (#333) 2019-01-13 19:04:54 +01:00
Otto Winter
94bd179256 Fix show logs with MQTT and dashboard (#332)
Fixes #327
2019-01-13 19:04:54 +01:00
Otto Winter
11c38ca4e8 Fix AsyncTCP compilation on ESP32 with Arduino breaking change (#334) 2019-01-13 19:04:54 +01:00
Otto Winter
dc71d11a21 Fix ESP32 not decoding stacktrace on broken PC (#330) 2019-01-13 19:04:53 +01:00
Otto Winter
e385c8435b Fix auto_uart 2019-01-10 10:56:25 +01:00
Otto Winter
13eca6012d Bump HassIO version to v1.10.0 2019-01-09 20:30:58 +01:00
Otto Winter
cb3e3e024d Bump version to v1.10.0 2019-01-09 20:29:28 +01:00
Otto Winter
79bdec32b8 Merge branch 'rc' 2019-01-09 20:29:15 +01:00
Otto Winter
c153dba5bc Fix Gitlab CI 2019-01-09 16:29:21 +01:00
Otto Winter
fa2c2917c1 Bump beta version to v1.10.0b2 2019-01-09 16:16:19 +01:00
Otto Winter
2a06f4dbf4 Bump version to v1.10.0b2 2019-01-09 16:14:47 +01:00
Otto Winter
49b618bb0c Fix interval trigger (#313) 2019-01-09 16:14:43 +01:00
escoand
20ec3900be use full space on small devices (#310)
* use full space on small devices

I often use my smartphone for quick actions and always was annoyed of this wasted space.

* hide card-image on small devices
2019-01-09 16:14:43 +01:00
Otto Winter
605be1a6ec OTA don't error when upgrading from no password to password mode (#309) 2019-01-09 16:14:43 +01:00
Otto Winter
33b67de32e Fix component.update action (#308)
Fixes https://github.com/OttoWinter/esphomeyaml/issues/286
2019-01-09 16:14:43 +01:00
Otto Winter
1ffedb291c Update beta config (#305)
* Update beta Hass.io add-on config

* Add README
2019-01-06 21:29:33 +01:00
Otto Winter
8f251848ef Bump beta version to v1.10.0b1 2019-01-06 19:39:15 +01:00
Otto Winter
4046a16d85 Merge branch 'dev' into rc 2019-01-06 19:38:23 +01:00
Otto Winter
5ed987adcd Bump HassIO version to v1.9.3 2018-12-01 13:38:05 +01:00
Otto Winter
a463c59733 Bump version to v1.9.3 2018-12-01 13:37:28 +01:00
Otto Winter
1726c4237b CSE7766 update interval (#250)
* CSE7766 update interval

* PollingComponent
2018-12-01 13:37:25 +01:00
Otto Winter
f1241af91d Bump HassIO version to v1.9.2 2018-11-25 19:18:17 +01:00
Otto Winter
7ae6777fd6 Bump version to v1.9.2 2018-11-25 19:17:32 +01:00
Otto Winter
a169d37557 Fix fastled lambda light effect
Fixes #232
2018-11-25 19:05:39 +01:00
Otto Winter
be21aa786d Bump HassIO version to v1.9.1 2018-11-19 23:05:18 +01:00
Otto Winter
9a881100e6 Bump version to v1.9.1 2018-11-19 23:04:56 +01:00
Otto Winter
c2f88776c7 Fix SNTP servers option (#237)
* Fix SNTP servers option

* Lint
2018-11-19 23:04:45 +01:00
Otto Winter
846fcb8ccd Bump HassIO version to v1.9.0 2018-11-15 12:07:23 +01:00
Otto Winter
44495c919c Bump version to v1.9.0 2018-11-15 12:05:25 +01:00
Otto Winter
d4ce7699d4 Merge branch 'rc' 2018-11-15 12:05:18 +01:00
Otto Winter
318bb8b254 Bump beta version to v1.9.0b6 2018-11-13 19:10:32 +01:00
Otto Winter
1ad65516cf Bump version to v1.9.0b6 2018-11-13 19:06:32 +01:00
Otto Winter
d4c7e6c634 Merge branch 'dev' into rc 2018-11-13 19:06:26 +01:00
Otto Winter
9a939d2d27 Bump beta version to v1.9.0b5 2018-11-12 23:44:57 +01:00
Otto Winter
06eeed9ee9 Bump version to v1.9.0b5 2018-11-12 23:43:03 +01:00
Otto Winter
5655b5fe10 Merge branch 'dev' into rc 2018-11-12 23:43:00 +01:00
Otto Winter
0dec7cfbf8 Lint 2018-11-10 15:39:25 +01:00
Otto Winter
f51d301d53 Bump beta version to v1.9.0b4 2018-11-10 15:33:03 +01:00
Otto Winter
30e7797577 Bump version to v1.9.0b4 2018-11-10 15:31:20 +01:00
Otto Winter
0e5cabadc1 Merge branch 'dev' into rc 2018-11-10 15:31:16 +01:00
Otto Winter
aa5f887ff3 Fix Gitlab CI 2018-11-04 00:10:44 +01:00
Otto Winter
28561ea6a4 Merge branch 'dev' into rc 2018-11-03 17:52:22 +01:00
Otto Winter
6b8125f5f2 Bump version to v1.9.0b3 2018-11-03 17:47:12 +01:00
Otto Winter
ab43390983 Merge branch 'dev' into rc 2018-11-03 17:47:06 +01:00
Otto Winter
d7d3a4aa36 Bump beta version to v1.10.0-dev 2018-11-03 12:09:22 +01:00
Otto Winter
4dce7fa103 Bump version to 1.9.0b2 2018-10-31 16:35:45 +01:00
Otto Winter
467ef9902f Merge branch 'dev' into rc 2018-10-31 16:34:36 +01:00
Otto Winter
6a2e9a8503 Add beta add-on 2018-10-20 19:15:49 +02:00
Otto Winter
74fefea5bb Fix gitlab 2018-10-20 19:14:27 +02:00
251 changed files with 2963 additions and 4677 deletions

49
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,49 @@
---
name: Bug report
about: Create a report to help esphomelib improve
---
<!-- Thanks for reporting a bug for this project. READ THIS FIRST:
- Please make sure to submit issues in the right GitHub repository, if unsure just post it here:
- esphomeyaml [here] - This is mostly for reporting bugs when compiling and when you get a long stack trace while compiling or if a configuration fails to validate.
- esphomelib [https://github.com/OttoWinter/esphomelib] - Report bugs there if the ESP is crashing or a feature is not working as expected.
- esphomedocs [https://github.com/OttoWinter/esphomedocs] - Report bugs there if the documentation is wrong/outdated.
- Provide as many details as possible. Paste logs, configuration sample and code into the backticks (```).
DO NOT DELETE ANY TEXT from this template! Otherwise the issue may be closed without a comment.
-->
**Operating environment (Hass.io/Docker/pip/etc.):**
<!--
Please provide details about your environment.
-->
**ESP (ESP32/ESP8266/Board/Sonoff):**
<!--
Please provide details about which ESP you're using.
-->
**Affected component:**
<!--
Please add the link to the documentation at https://esphomelib.com/esphomeyaml/index.html of the component in question.
-->
**Description of problem:**
**Problem-relevant YAML-configuration entries:**
```yaml
PASTE YAML FILE HERE
```
**Traceback (if applicable):**
<!--
Please copy the traceback here if compilation is failing. If possible, also connect to the ESP and copy its logs into the backticks.
-->
```
```
**Additional information:**

View File

@@ -0,0 +1,21 @@
---
name: Feature request
about: Suggest an idea for this project
---
<!-- READ THIS FIRST:
- This is for feature requests only, if you want to have a certain new sensor/module supported, please use the "new integration" template.
- Please be as descriptive as possible, especially use-cases that can otherwise not be solved boost the problem's priority.
DO NOT DELETE ANY TEXT from this template! Otherwise the issue may be closed without a comment.
-->
**Is your feature request related to a problem/use-case? Please describe.**
<!-- A clear and concise description of what the problem is. -->
**Describe the solution you'd like:**
<!-- A description of what you want to happen. -->
**Additional context:**
<!-- Add any other context about the feature request here. -->

View File

@@ -0,0 +1,13 @@
---
name: New integration
about: Suggest a new integration for esphomelib
---
DO NOT POST NEW INTEGRATION REQUESTS HERE!
Please post all new integration requests in the esphomelib repository:
https://github.com/OttoWinter/esphomelib/issues
Thank you!

View File

@@ -3,8 +3,8 @@
**Related issue (if applicable):** fixes <link to issue>
**Pull request in [esphome-docs](https://github.com/esphome/esphome-docs) with documentation (if applicable):** esphome/esphome-docs#<esphome-docs PR number goes here>
**Pull request in [esphome-core](https://github.com/esphome/esphome-core) with C++ framework changes (if applicable):** esphome/esphome-core#<esphome-core PR number goes here>
**Pull request in [esphomedocs](https://github.com/OttoWinter/esphomedocs) with documentation (if applicable):** OttoWinter/esphomedocs#<esphomedocs PR number goes here>
**Pull request in [esphomelib](https://github.com/OttoWinter/esphomelib) with C++ framework changes (if applicable):** OttoWinter/esphomelib#<esphomelib PR number goes here>
## Checklist:
- [ ] The code change is tested and works locally.

2
.gitignore vendored
View File

@@ -105,4 +105,4 @@ venv.bak/
config/
tests/build/
tests/.esphome/
tests/.esphomeyaml/

View File

@@ -2,126 +2,293 @@
# Based on https://gitlab.com/hassio-addons/addon-node-red/blob/master/.gitlab-ci.yml
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375/
stages:
- lint
- test
- build
- deploy
.lint: &lint
image: esphome/esphome-base-amd64
stage: lint
before_script:
- pip install -e .
- pip install flake8==3.6.0 pylint==1.9.4 pillow
tags:
- docker
- python2.7
- esphomeyaml-lint
.test: &test
image: esphome/esphome-base-amd64
stage: test
before_script:
- pip install -e .
tags:
- docker
- python2.7
- esphomeyaml-test
variables:
TZ: UTC
.docker-base: &docker-base
image: esphome/esphome-base-builder
.docker-builder: &docker-builder
before_script:
- docker info
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
script:
- docker run --rm --privileged hassioaddons/qemu-user-static:latest
- TAG="${CI_COMMIT_TAG#v}"
- TAG="${TAG:-${CI_COMMIT_SHA:0:7}}"
- echo "Tag ${TAG}"
- |
if [[ "${IS_HASSIO}" == "YES" ]]; then
BUILD_FROM=esphome/esphome-hassio-base-${BUILD_ARCH}:1.2.1
BUILD_TO=esphome/esphome-hassio-${BUILD_ARCH}
DOCKERFILE=docker/Dockerfile.hassio
else
BUILD_FROM=esphome/esphome-base-${BUILD_ARCH}:1.2.1
if [[ "${BUILD_ARCH}" == "amd64" ]]; then
BUILD_TO=esphome/esphome
else
BUILD_TO=esphome/esphome-${BUILD_ARCH}
fi
DOCKERFILE=docker/Dockerfile
fi
- |
docker build \
--build-arg "BUILD_FROM=${BUILD_FROM}" \
--build-arg "BUILD_VERSION=${TAG}" \
--tag "${BUILD_TO}:${TAG}" \
--file "${DOCKERFILE}" \
.
- |
if [[ "${RELEASE}" = "YES" ]]; then
echo "Pushing to ${BUILD_TO}:${TAG}"
docker push "${BUILD_TO}:${TAG}"
fi
- |
if [[ "${LATEST}" = "YES" ]]; then
echo "Pushing to :latest"
docker tag ${BUILD_TO}:${TAG} ${BUILD_TO}:latest
docker push ${BUILD_TO}:latest
fi
- |
if [[ "${BETA}" = "YES" ]]; then
echo "Pushing to :beta"
docker tag \
${BUILD_TO}:${TAG} \
${BUILD_TO}:beta
docker push ${BUILD_TO}:beta
fi
- |
if [[ "${DEV}" = "YES" ]]; then
echo "Pushing to :dev"
docker tag \
${BUILD_TO}:${TAG} \
${BUILD_TO}:dev
docker push ${BUILD_TO}:dev
fi
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
services:
- docker:dind
tags:
- docker
stage: deploy
- hassio-builder
flake8:
<<: *lint
script:
- flake8 esphome
- flake8 esphomeyaml
pylint:
<<: *lint
script:
- pylint esphome
- pylint esphomeyaml
test1:
<<: *test
script:
- esphome tests/test1.yaml compile
- esphomeyaml tests/test1.yaml compile
test2:
<<: *test
script:
- esphome tests/test2.yaml compile
- esphomeyaml tests/test2.yaml compile
test3:
<<: *test
.build-hassio: &build-hassio
<<: *docker-builder
stage: build
script:
- esphome tests/test3.yaml compile
- docker run --rm --privileged hassioaddons/qemu-user-static: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}}"
- echo "Build from ${BUILD_FROM}"
- echo "Add-on version ${ADDON_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 "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}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:dev" \
--tag "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
--file "docker/Dockerfile.hassio" \
.
- |
if [ "${DO_PUSH:-true}" = true ]; then
echo "Pushing to CI registry"
docker push ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}
docker push ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:dev
fi
# Generic deploy template
.deploy-release: &deploy-release
<<: *docker-builder
stage: deploy
script:
- version="${CI_COMMIT_TAG#v}"
- echo "Publishing release version ${version}"
- docker pull "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
- echo "Tag ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- echo "Tag ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- echo "Tag ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- |
docker tag \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}" \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- |
docker tag \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}" \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
only:
- /^v\d+\.\d+\.\d+$/
except:
- /^(?!master).+@/
.deploy-beta: &deploy-beta
<<: *docker-builder
stage: deploy
script:
- version="${CI_COMMIT_TAG#v}"
- echo "Publishing beta version ${version}"
- docker pull "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
- echo "Tag ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- echo "Tag ${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- |
docker tag \
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- |
docker tag \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}" \
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
only:
- /^v\d+\.\d+\.\d+b\d+$/
except:
- /^(?!rc).+@/
# Build jobs
build:normal:
<<: *docker-builder
stage: build
script:
- docker build -t "${CI_REGISTRY}/ottowinter/esphomeyaml:dev" .
.build-hassio-edge: &build-hassio-edge
<<: *build-hassio
except:
- /^v\d+\.\d+\.\d+$/
- /^v\d+\.\d+\.\d+b\d+$/
.build-hassio-release: &build-hassio-release
<<: *build-hassio
only:
- /^v\d+\.\d+\.\d+$/
- /^v\d+\.\d+\.\d+b\d+$/
build:hassio-armhf-edge:
<<: *build-hassio-edge
variables:
ADDON_ARCH: armhf
DO_PUSH: "false"
build:hassio-armhf:
<<: *build-hassio-release
variables:
ADDON_ARCH: armhf
#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-i386-edge:
<<: *build-hassio-edge
variables:
ADDON_ARCH: i386
DO_PUSH: "false"
build:hassio-i386:
<<: *build-hassio-release
variables:
ADDON_ARCH: i386
build:hassio-amd64-edge:
<<: *build-hassio-edge
variables:
ADDON_ARCH: amd64
DO_PUSH: "false"
build:hassio-amd64:
<<: *build-hassio-release
variables:
ADDON_ARCH: amd64
# Deploy jobs
deploy-release:armhf:
<<: *deploy-release
variables:
ADDON_ARCH: armhf
deploy-beta:armhf:
<<: *deploy-beta
variables:
ADDON_ARCH: armhf
#deploy-release:aarch64:
# <<: *deploy-release
# variables:
# ADDON_ARCH: aarch64
#deploy-beta:aarch64:
# <<: *deploy-beta
# variables:
# ADDON_ARCH: aarch64
deploy-release:i386:
<<: *deploy-release
variables:
ADDON_ARCH: i386
deploy-beta:i386:
<<: *deploy-beta
variables:
ADDON_ARCH: i386
deploy-release:amd64:
<<: *deploy-release
variables:
ADDON_ARCH: amd64
deploy-beta:amd64:
<<: *deploy-beta
variables:
ADDON_ARCH: amd64
.deploy-pypi: &deploy-pypi
stage: deploy
image: python:2.7
before_script:
- pip install -e .
- pip install twine
@@ -129,7 +296,8 @@ test3:
- python setup.py sdist
- twine upload dist/*
tags:
- docker
- python2.7
- esphomeyaml-test
deploy-release:pypi:
<<: *deploy-pypi
@@ -144,204 +312,3 @@ deploy-beta:pypi:
- /^v\d+\.\d+\.\d+b\d+$/
except:
- /^(?!rc).+@/
.latest: &latest
<<: *docker-base
only:
- /^v([0-9\.]+)$/
except:
- branches
.latest-vars: &latest-vars
RELEASE: YES
LATEST: YES
# Also push to beta tag
BETA: YES
.beta: &beta
<<: *docker-base
only:
- /^v([0-9\.]+b\d+)$/
except:
- branches
.beta-vars: &beta-vars
RELEASE: YES
BETA: YES
.dev: &dev
<<: *docker-base
only:
- dev
.dev-vars: &dev-vars
DEV: YES
aarch64-beta-docker:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: aarch64
IS_HASSIO: "NO"
RELEASE: "YES"
aarch64-beta-hassio:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: aarch64
IS_HASSIO: "YES"
RELEASE: "YES"
aarch64-dev-docker:
<<: *dev
variables:
BUILD_ARCH: aarch64
DEV: "YES"
IS_HASSIO: "NO"
aarch64-dev-hassio:
<<: *dev
variables:
BUILD_ARCH: aarch64
DEV: "YES"
IS_HASSIO: "YES"
aarch64-latest-docker:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: aarch64
IS_HASSIO: "NO"
LATEST: "YES"
RELEASE: "YES"
aarch64-latest-hassio:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: aarch64
IS_HASSIO: "YES"
LATEST: "YES"
RELEASE: "YES"
amd64-beta-docker:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: amd64
IS_HASSIO: "NO"
RELEASE: "YES"
amd64-beta-hassio:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: amd64
IS_HASSIO: "YES"
RELEASE: "YES"
amd64-dev-docker:
<<: *dev
variables:
BUILD_ARCH: amd64
DEV: "YES"
IS_HASSIO: "NO"
amd64-dev-hassio:
<<: *dev
variables:
BUILD_ARCH: amd64
DEV: "YES"
IS_HASSIO: "YES"
amd64-latest-docker:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: amd64
IS_HASSIO: "NO"
LATEST: "YES"
RELEASE: "YES"
amd64-latest-hassio:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: amd64
IS_HASSIO: "YES"
LATEST: "YES"
RELEASE: "YES"
armhf-beta-docker:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: armhf
IS_HASSIO: "NO"
RELEASE: "YES"
armhf-beta-hassio:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: armhf
IS_HASSIO: "YES"
RELEASE: "YES"
armhf-dev-docker:
<<: *dev
variables:
BUILD_ARCH: armhf
DEV: "YES"
IS_HASSIO: "NO"
armhf-dev-hassio:
<<: *dev
variables:
BUILD_ARCH: armhf
DEV: "YES"
IS_HASSIO: "YES"
armhf-latest-docker:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: armhf
IS_HASSIO: "NO"
LATEST: "YES"
RELEASE: "YES"
armhf-latest-hassio:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: armhf
IS_HASSIO: "YES"
LATEST: "YES"
RELEASE: "YES"
i386-beta-docker:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: i386
IS_HASSIO: "NO"
RELEASE: "YES"
i386-beta-hassio:
<<: *beta
variables:
BETA: "YES"
BUILD_ARCH: i386
IS_HASSIO: "YES"
RELEASE: "YES"
i386-dev-docker:
<<: *dev
variables:
BUILD_ARCH: i386
DEV: "YES"
IS_HASSIO: "NO"
i386-dev-hassio:
<<: *dev
variables:
BUILD_ARCH: i386
DEV: "YES"
IS_HASSIO: "YES"
i386-latest-docker:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: i386
IS_HASSIO: "NO"
LATEST: "YES"
RELEASE: "YES"
i386-latest-hassio:
<<: *latest
variables:
BETA: "YES"
BUILD_ARCH: i386
IS_HASSIO: "YES"
LATEST: "YES"
RELEASE: "YES"

View File

@@ -8,24 +8,23 @@ matrix:
env: TARGET=Lint2.7
install: pip install -e . && pip install flake8==3.6.0 pylint==1.9.4 pillow
script:
- flake8 esphome
- pylint esphome
- flake8 esphomeyaml
- pylint esphomeyaml
- python: "3.5.3"
env: TARGET=Lint3.5
install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 pillow
script:
- flake8 esphome
- pylint esphome
- flake8 esphomeyaml
- pylint esphomeyaml
- python: "2.7"
env: TARGET=Test2.7
install: pip install -e . && pip install flake8==3.6.0 pylint==1.9.4 pillow
script:
- esphome tests/test1.yaml compile
- esphome tests/test2.yaml compile
- esphome tests/test3.yaml compile
#- python: "3.5.3"
# env: TARGET=Test3.5
# install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 pillow
# script:
# - esphome tests/test1.yaml compile
# - esphome tests/test2.yaml compile
- esphomeyaml tests/test1.yaml compile
- esphomeyaml tests/test2.yaml compile
- python: "3.5.3"
env: TARGET=Test3.5
install: pip install -U https://github.com/platformio/platformio-core/archive/develop.zip && pip install -e . && pip install flake8==3.6.0 pylint==2.2.2 pillow
script:
- esphomeyaml tests/test1.yaml compile
- esphomeyaml tests/test2.yaml compile

View File

@@ -1,16 +1,16 @@
# Contributing to ESPHome
# Contributing to esphomeyaml
This python project is responsible for reading in YAML configuration files,
esphomeyaml is a part of esphomelib and is responsible for reading in YAML configuration files,
converting them to C++ code. This code is then converted to a platformio project and compiled
with [esphome-core](https://github.com/esphome/esphome-core), the C++ framework behind the project.
with [esphomelib](https://github.com/OttoWinter/esphomelib), the C++ framework behind the project.
For a detailed guide, please see https://esphome.io/guides/contributing.html#contributing-to-esphomeyaml
For a detailed guide, please see https://esphomelib.com/esphomeyaml/guides/contributing.html#contributing-to-esphomeyaml
Things to note when contributing:
- Please test your changes :)
- If a new feature is added or an existing user-facing feature is changed, you should also
update the [docs](https://github.com/esphome/esphome-docs). See [contributing to esphome-docs](https://esphome.io/guides/contributing.html#contributing-to-esphomedocs)
update the [docs](https://github.com/OttoWinter/esphomedocs). See [contributing to esphomedocs](https://esphomelib.com/esphomeyaml/guides/contributing.html#contributing-to-esphomedocs)
for more information.
- Please also update the tests in the `tests/` folder. You can do so by just adding a line in one of the YAML files
which checks if your new feature compiles correctly.

28
Dockerfile Normal file
View File

@@ -0,0 +1,28 @@
ARG BUILD_FROM=python:2.7
FROM ${BUILD_FROM}
MAINTAINER Otto Winter <contact@otto-winter.com>
RUN apt-get update && apt-get install -y \
python-pil \
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
ENV ESPHOMEYAML_OTA_HOST_PORT=6123
EXPOSE 6123
VOLUME /config
WORKDIR /usr/src/app
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 .
WORKDIR /config
ENTRYPOINT ["esphomeyaml"]
CMD ["/config", "dashboard"]

View File

@@ -1,17 +1,17 @@
include README.md
include esphome/dashboard/templates/index.html
include esphome/dashboard/templates/login.html
include esphome/dashboard/static/ace.js
include esphome/dashboard/static/esphome.css
include esphome/dashboard/static/esphome.js
include esphome/dashboard/static/favicon.ico
include esphome/dashboard/static/jquery.min.js
include esphome/dashboard/static/jquery.validate.min.js
include esphome/dashboard/static/jquery-ui.min.js
include esphome/dashboard/static/materialize.min.css
include esphome/dashboard/static/materialize.min.js
include esphome/dashboard/static/materialize-stepper.min.css
include esphome/dashboard/static/materialize-stepper.min.js
include esphome/dashboard/static/mode-yaml.js
include esphome/dashboard/static/theme-dreamweaver.js
include esphome/dashboard/static/ext-searchbox.js
include 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
include esphomeyaml/dashboard/static/ext-searchbox.js

View File

@@ -1,9 +1,38 @@
# ESPHome [![Build Status](https://travis-ci.org/esphome/esphome.svg?branch=master)](https://travis-ci.org/esphome/esphome) [![Discord Chat](https://img.shields.io/discord/429907082951524364.svg)](https://discord.gg/KhAMKrd) [![GitHub release](https://img.shields.io/github/release/esphome/esphome.svg)](https://GitHub.com/esphome/esphome/releases/)
# esphomeyaml for [esphomelib](https://github.com/OttoWinter/esphomelib)
[![ESPHome Logo](https://esphome.io/_images/logo-text.png)](https://esphome.io/)
### Getting Started Guide: https://esphomelib.com/esphomeyaml/guides/getting_started_command_line.html
**Documentation:** https://esphome.io/
### Available Components: https://esphomelib.com/esphomeyaml/index.html
For issues, please go to [the issue tracker](https://github.com/esphome/issues/issues).
esphomeyaml is the solution for your ESP8266/ESP32 projects with Home Assistant. It allows you to create **custom firmwares** for your microcontrollers with no programming experience required. All you need to know is the YAML configuration format which is also used by [Home Assistant](https://www.home-assistant.io).
For feature requests, please see [feature requests](https://github.com/esphome/feature-requests/issues).
esphomeyaml will:
* Read your configuration file and warn you about potential errors (like using the invalid pins.)
* Create a custom C++ sketch file for you using esphomeyaml's powerful C++ generation engine.
* Compile the sketch file for you using [platformio](http://platformio.org/).
* Upload the binary to your ESP via Over the Air updates.
* Automatically start remote logs via MQTT.
And all of that with a single command 🎉:
```bash
esphomeyaml configuration.yaml run
```
## Features
* **No programming experience required:** just edit YAML configuration
files like you're used to with Home Assistant.
* **Flexible:** Use [esphomelib](https://github.com/OttoWinter/esphomelib)'s powerful core to create custom sensors/outputs.
* **Fast and efficient:** Written in C++ and keeps memory consumption to a minimum.
* **Made for [Home Assistant](https://www.home-assistant.io):** Almost all [Home Assistant](https://www.home-assistant.io) features are supported out of the box. Including RGB lights and many more.
* **Easy reproducible configuration:** No need to go through a long setup process for every single node. Just copy a configuration file and run a single command.
* **Smart Over The Air Updates:** esphomeyaml has OTA updates deeply integrated into the system. It even automatically enters a recovery mode if a boot loop is detected.
* **Powerful logging engine:** View colorful logs and debug issues remotely.
* **Open Source**
* For me: Makes documenting esphomelib's features a lot easier.
## Special Thanks
Special Thanks to the Home Assistant project. Lots of the code base of esphomeyaml is based off of Home Assistant, for example the loading and config validation code.

View File

@@ -1,10 +0,0 @@
ARG BUILD_FROM=esphome/esphome-base-amd64:1.2.1
FROM ${BUILD_FROM}
COPY . .
RUN \
pip2 install --no-cache-dir --no-binary :all: -e .
WORKDIR /config
ENTRYPOINT ["esphome"]
CMD ["/config", "dashboard"]

30
docker/Dockerfile.builder Normal file
View File

@@ -0,0 +1,30 @@
FROM multiarch/ubuntu-core:amd64-xenial
# setup locals
RUN apt-get update && apt-get install -y \
jq \
git \
python3-setuptools \
&& rm -rf /var/lib/apt/lists/* \
ENV LANG C.UTF-8
# Install docker
# https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/
RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
software-properties-common \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \
&& add-apt-repository "deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
&& apt-get update && apt-get install -y docker-ce \
&& rm -rf /var/lib/apt/lists/*
# setup arm binary support
RUN apt-get update && apt-get install -y \
qemu-user-static \
binfmt-support \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /data

View File

@@ -1,20 +1,75 @@
ARG BUILD_FROM=esphome/esphome-hassio-base-amd64:1.2.1
ARG BUILD_FROM=hassioaddons/ubuntu-base:2.2.0
# hadolint ignore=DL3006
FROM ${BUILD_FROM}
# Set shell
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Copy root filesystem
COPY docker/rootfs/ /
COPY setup.py setup.cfg MANIFEST.in /opt/esphome/
COPY esphome /opt/esphome/esphome
COPY esphomeyaml-edge/rootfs /
COPY setup.py setup.cfg MANIFEST.in /opt/esphomeyaml/
COPY esphomeyaml /opt/esphomeyaml/esphomeyaml
RUN \
pip2 install --no-cache-dir --no-binary :all: -e /opt/esphome
# 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 \
# 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 \
\
# 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 arguments
ARG BUILD_VERSION=dev
# Build arugments
ARG BUILD_ARCH=amd64
ARG BUILD_DATE
ARG BUILD_REF
ARG BUILD_VERSION
# Labels
LABEL \
io.hass.name="ESPHome" \
io.hass.name="esphomeyaml" \
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}
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"

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
# the Docker repository tag being built.
declare CACHE_TAG
echo "CACHE_TAG: ${CACHE_TAG}"
# the name and tag of the Docker repository being built. (This variable is a combination of DOCKER_REPO:CACHE_TAG.)
declare IMAGE_NAME
echo "IMAGE_NAME: ${IMAGE_NAME}"
# the architecture to build
declare BUILD_ARCH
echo "BUILD_ARCH: ${BUILD_ARCH}"
# whether this is a hassio build
declare IS_HASSIO
echo "IS_HASSIO: ${IS_HASSIO}"
echo "PWD: $PWD"
if [[ ${IS_HASSIO} = "YES" ]]; then
docker build \
--build-arg "BUILD_FROM=esphome/esphome-hassio-base-${BUILD_ARCH}:1.2.1" \
--build-arg "BUILD_VERSION=${CACHE_TAG}" \
-t "${IMAGE_NAME}" -f ../docker/Dockerfile.hassio ..
else
docker build \
--build-arg "BUILD_FROM=esphome/esphome-base-${BUILD_ARCH}:1.2.1" \
-t "${IMAGE_NAME}" -f ../docker/Dockerfile ..
fi

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env bash
# the architecture to build
declare BUILD_ARCH
echo "BUILD_ARCH: ${BUILD_ARCH}"
if [[ ${BUILD_ARCH} = "amd64" ]]; then
echo "No qemu required..."
exit 0
fi
if [[ ${BUILD_ARCH} = "i386" ]]; then
echo "No qemu required..."
exit 0
fi
echo "Installing qemu..."
docker run --rm --privileged multiarch/qemu-user-static:register --reset

View File

@@ -1,35 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files check if all user configuration requirements are met
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
# Check SSL requirements, if enabled
if hass.config.true 'ssl'; then
if ! hass.config.has_value 'certfile'; then
hass.die 'SSL is enabled, but no certfile was specified.'
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 ESPHome 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

View File

@@ -1,28 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Configures NGINX for use with ESPHome
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
declare certfile
declare keyfile
declare port
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
port=$(hass.config.get 'port')
sed -i "s/%%port%%/${port}/g" /etc/nginx/nginx.conf

View File

@@ -1,14 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files installs the user ESPHome version if specified
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
declare esphome_version
if hass.config.has_value 'esphome_version'; then
esphome_version=$(hass.config.get 'esphome_version')
pip2 install --no-cache-dir --no-binary :all: "https://github.com/esphome/esphome/archive/${esphome_version}.zip"
fi

View File

@@ -1,13 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files migrates the esphome config directory from the old path
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
if [[ ! -d /config/esphome && -d /config/esphomeyaml ]]; then
echo "Moving config directory from /config/esphomeyaml to /config/esphome"
mv /config/esphomeyaml /config/esphome
mv /config/esphome/.esphomeyaml /config/esphome/.esphome
fi

View File

@@ -1,62 +0,0 @@
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 esphome {
ip_hash;
server unix:/var/run/esphome.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
server_name hassio.local;
listen %%port%% 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://esphome;
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;
}
}
}

View File

@@ -1,46 +0,0 @@
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 esphome {
ip_hash;
server unix:/var/run/esphome.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
server_name hassio.local;
listen %%port%% default_server;
root /dev/null;
location / {
proxy_redirect off;
proxy_pass http://esphome;
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;
}
}
}

View File

@@ -1,14 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Runs the ESPHome dashboard
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
if hass.config.true 'leave_front_door_open'; then
export DISABLE_HA_AUTHENTICATION=true
fi
hass.log.info "Starting ESPHome dashboard..."
exec esphome /config/esphome dashboard --socket /var/run/esphome.sock --hassio

View File

@@ -1,9 +0,0 @@
#!/usr/bin/execlineb -S0
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# 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

View File

@@ -1,10 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Runs the NGINX proxy
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
hass.log.info "Starting NGINX..."
exec nginx -g "daemon off;"

View File

@@ -1,30 +0,0 @@
import voluptuous as vol
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_ENTITY_ID, CONF_ID, CONF_NAME
from esphome.cpp_generator import Pvariable
from esphome.cpp_types import App
DEPENDENCIES = ['api']
HomeassistantBinarySensor = binary_sensor.binary_sensor_ns.class_('HomeassistantBinarySensor',
binary_sensor.BinarySensor)
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HomeassistantBinarySensor),
vol.Required(CONF_ENTITY_ID): cv.entity_id,
}))
def to_code(config):
rhs = App.make_homeassistant_binary_sensor(config[CONF_NAME], config[CONF_ENTITY_ID])
subs = Pvariable(config[CONF_ID], rhs)
binary_sensor.setup_binary_sensor(subs, config)
BUILD_FLAGS = '-DUSE_HOMEASSISTANT_BINARY_SENSOR'
def to_hass_config(data, config):
return binary_sensor.core_to_hass_config(data, config)

View File

@@ -1,60 +0,0 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_STATE
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Action, App, Component, bool_, optional
TemplateBinarySensor = binary_sensor.binary_sensor_ns.class_('TemplateBinarySensor',
binary_sensor.BinarySensor,
Component)
BinarySensorPublishAction = binary_sensor.binary_sensor_ns.class_('BinarySensorPublishAction',
Action)
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateBinarySensor),
vol.Optional(CONF_LAMBDA): cv.lambda_,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_binary_sensor(config[CONF_NAME])
var = Pvariable(config[CONF_ID], rhs)
binary_sensor.setup_binary_sensor(var, config)
setup_component(var, config)
if CONF_LAMBDA in config:
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(bool_)):
yield
add(var.set_template(template_))
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'
CONF_BINARY_SENSOR_TEMPLATE_PUBLISH = 'binary_sensor.template.publish'
BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
vol.Required(CONF_ID): cv.use_variable_id(binary_sensor.BinarySensor),
vol.Required(CONF_STATE): cv.templatable(cv.boolean),
})
@ACTION_REGISTRY.register(CONF_BINARY_SENSOR_TEMPLATE_PUBLISH,
BINARY_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA)
def binary_sensor_template_publish_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
rhs = var.make_binary_sensor_publish_action(template_arg)
type = BinarySensorPublishAction.template(arg_type)
action = Pvariable(action_id, rhs, type=type)
for template_ in templatable(config[CONF_STATE], arg_type, bool_):
yield None
add(action.set_state(template_))
yield action
def to_hass_config(data, config):
return binary_sensor.core_to_hass_config(data, config)

View File

@@ -1,88 +0,0 @@
import voluptuous as vol
from esphome import automation
from esphome.automation import ACTION_REGISTRY
from esphome.components import cover
import esphome.config_validation as cv
from esphome.const import CONF_ASSUMED_STATE, CONF_CLOSE_ACTION, CONF_ID, CONF_LAMBDA, CONF_NAME, \
CONF_OPEN_ACTION, CONF_OPTIMISTIC, CONF_STATE, CONF_STOP_ACTION
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Action, App, NoArg, optional
from esphome.py_compat import string_types
TemplateCover = cover.cover_ns.class_('TemplateCover', cover.Cover)
CoverPublishAction = cover.cover_ns.class_('CoverPublishAction', Action)
PLATFORM_SCHEMA = cv.nameable(cover.COVER_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateCover),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_ASSUMED_STATE): cv.boolean,
vol.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True),
vol.Optional(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
vol.Optional(CONF_STOP_ACTION): automation.validate_automation(single=True),
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_cover(config[CONF_NAME])
var = Pvariable(config[CONF_ID], rhs)
cover.setup_cover(var, config)
setup_component(var, config)
if CONF_LAMBDA in config:
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(cover.CoverState)):
yield
add(var.set_state_lambda(template_))
if CONF_OPEN_ACTION in config:
automation.build_automation(var.get_open_trigger(), NoArg,
config[CONF_OPEN_ACTION])
if CONF_CLOSE_ACTION in config:
automation.build_automation(var.get_close_trigger(), NoArg,
config[CONF_CLOSE_ACTION])
if CONF_STOP_ACTION in config:
automation.build_automation(var.get_stop_trigger(), NoArg,
config[CONF_STOP_ACTION])
if CONF_OPTIMISTIC in config:
add(var.set_optimistic(config[CONF_OPTIMISTIC]))
if CONF_ASSUMED_STATE in config:
add(var.set_assumed_state(config[CONF_ASSUMED_STATE]))
BUILD_FLAGS = '-DUSE_TEMPLATE_COVER'
CONF_COVER_TEMPLATE_PUBLISH = 'cover.template.publish'
COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
vol.Required(CONF_ID): cv.use_variable_id(cover.Cover),
vol.Required(CONF_STATE): cv.templatable(cover.validate_cover_state),
})
@ACTION_REGISTRY.register(CONF_COVER_TEMPLATE_PUBLISH,
COVER_TEMPLATE_PUBLISH_ACTION_SCHEMA)
def cover_template_publish_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
rhs = var.make_cover_publish_action(template_arg)
type = CoverPublishAction.template(arg_type)
action = Pvariable(action_id, rhs, type=type)
state = config[CONF_STATE]
if isinstance(state, string_types):
template_ = cover.COVER_STATES[state]
else:
for template_ in templatable(state, arg_type, cover.CoverState):
yield None
add(action.set_state(template_))
yield action
def to_hass_config(data, config):
ret = cover.core_to_hass_config(data, config)
if ret is None:
return None
if CONF_OPTIMISTIC in config:
ret['optimistic'] = config[CONF_OPTIMISTIC]
return ret

View File

@@ -1,127 +0,0 @@
# coding=utf-8
import voluptuous as vol
from esphome import core
from esphome.automation import ACTION_REGISTRY, maybe_simple_id
import esphome.config_validation as cv
from esphome.const import CONF_LAMBDA, CONF_ROTATION, CONF_UPDATE_INTERVAL, CONF_PAGES, CONF_ID
from esphome.core import CORE
from esphome.cpp_generator import add, process_lambda, Pvariable, templatable, get_variable
from esphome.cpp_types import esphome_ns, void, Action
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
display_ns = esphome_ns.namespace('display')
DisplayBuffer = display_ns.class_('DisplayBuffer')
DisplayPage = display_ns.class_('DisplayPage')
DisplayPagePtr = DisplayPage.operator('ptr')
DisplayBufferRef = DisplayBuffer.operator('ref')
DisplayPageShowAction = display_ns.class_('DisplayPageShowAction', Action)
DisplayPageShowNextAction = display_ns.class_('DisplayPageShowNextAction', Action)
DisplayPageShowPrevAction = display_ns.class_('DisplayPageShowPrevAction', Action)
DISPLAY_ROTATIONS = {
0: display_ns.DISPLAY_ROTATION_0_DEGREES,
90: display_ns.DISPLAY_ROTATION_90_DEGREES,
180: display_ns.DISPLAY_ROTATION_180_DEGREES,
270: display_ns.DISPLAY_ROTATION_270_DEGREES,
}
def validate_rotation(value):
value = cv.string(value)
if value.endswith(u"°"):
value = value[:-1]
try:
value = int(value)
except ValueError:
raise vol.Invalid(u"Expected integer for rotation")
return cv.one_of(*DISPLAY_ROTATIONS)(value)
BASIC_DISPLAY_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
vol.Optional(CONF_LAMBDA): cv.lambda_,
})
FULL_DISPLAY_PLATFORM_SCHEMA = BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_ROTATION): validate_rotation,
vol.Optional(CONF_PAGES): vol.All(cv.ensure_list({
cv.GenerateID(): cv.declare_variable_id(DisplayPage),
vol.Required(CONF_LAMBDA): cv.lambda_,
}), vol.Length(min=1)),
})
def setup_display_core_(display_var, config):
if CONF_UPDATE_INTERVAL in config:
add(display_var.set_update_interval(config[CONF_UPDATE_INTERVAL]))
if CONF_ROTATION in config:
add(display_var.set_rotation(DISPLAY_ROTATIONS[config[CONF_ROTATION]]))
if CONF_PAGES in config:
pages = []
for conf in config[CONF_PAGES]:
for lambda_ in process_lambda(conf[CONF_LAMBDA], [(DisplayBufferRef, 'it')],
return_type=void):
yield
var = Pvariable(conf[CONF_ID], DisplayPage.new(lambda_))
pages.append(var)
add(display_var.set_pages(pages))
CONF_DISPLAY_PAGE_SHOW = 'display.page.show'
DISPLAY_PAGE_SHOW_ACTION_SCHEMA = maybe_simple_id({
vol.Required(CONF_ID): cv.templatable(cv.use_variable_id(DisplayPage)),
})
@ACTION_REGISTRY.register(CONF_DISPLAY_PAGE_SHOW, DISPLAY_PAGE_SHOW_ACTION_SCHEMA)
def display_page_show_to_code(config, action_id, arg_type, template_arg):
type = DisplayPageShowAction.template(arg_type)
action = Pvariable(action_id, type.new(), type=type)
if isinstance(config[CONF_ID], core.Lambda):
for template_ in templatable(config[CONF_ID], arg_type, DisplayPagePtr):
yield None
add(action.set_page(template_))
else:
for var in get_variable(config[CONF_ID]):
yield None
add(action.set_page(var))
yield action
CONF_DISPLAY_PAGE_SHOW_NEXT = 'display.page.show_next'
DISPLAY_PAGE_SHOW_NEXT_ACTION_SCHEMA = maybe_simple_id({
vol.Required(CONF_ID): cv.templatable(cv.use_variable_id(DisplayBuffer)),
})
@ACTION_REGISTRY.register(CONF_DISPLAY_PAGE_SHOW_NEXT, DISPLAY_PAGE_SHOW_NEXT_ACTION_SCHEMA)
def display_page_show_next_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
type = DisplayPageShowNextAction.template(arg_type)
yield Pvariable(action_id, type.new(var), type=type)
CONF_DISPLAY_PAGE_SHOW_PREVIOUS = 'display.page.show_previous'
DISPLAY_PAGE_SHOW_PREVIOUS_ACTION_SCHEMA = maybe_simple_id({
vol.Required(CONF_ID): cv.templatable(cv.use_variable_id(DisplayBuffer)),
})
@ACTION_REGISTRY.register(CONF_DISPLAY_PAGE_SHOW_PREVIOUS, DISPLAY_PAGE_SHOW_PREVIOUS_ACTION_SCHEMA)
def display_page_show_previous_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
type = DisplayPageShowPrevAction.template(arg_type)
yield Pvariable(action_id, type.new(var), type=type)
def setup_display(display_var, config):
CORE.add_job(setup_display_core_, display_var, config)
BUILD_FLAGS = '-DUSE_DISPLAY'

View File

@@ -1,40 +0,0 @@
import voluptuous as vol
from esphome import config_validation as cv
from esphome.components import sensor
from esphome.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32
from esphome.core import HexInt
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component, esphome_ns
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
CONF_ESP32_BLE_ID = 'esp32_ble_id'
ESP32BLETracker = esphome_ns.class_('ESP32BLETracker', Component)
XiaomiSensor = esphome_ns.class_('XiaomiSensor', sensor.Sensor)
XiaomiDevice = esphome_ns.class_('XiaomiDevice')
XIAOMI_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(XiaomiSensor)
})
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_seconds,
}).extend(cv.COMPONENT_SCHEMA.schema)
def make_address_array(address):
return [HexInt(i) for i in address.parts]
def to_code(config):
rhs = App.make_esp32_ble_tracker()
ble = Pvariable(config[CONF_ID], rhs)
if CONF_SCAN_INTERVAL in config:
add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL]))
setup_component(ble, config)
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'

View File

@@ -1,52 +0,0 @@
import voluptuous as vol
from esphome.components import light
from esphome.components.light import AddressableLight
import esphome.config_validation as cv
from esphome.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_FROM, CONF_ID, \
CONF_MAKE_ID, CONF_NAME, CONF_SEGMENTS, CONF_TO
from esphome.cpp_generator import get_variable, variable
from esphome.cpp_types import App, Application
AddressableSegment = light.light_ns.class_('AddressableSegment')
PartitionLightOutput = light.light_ns.class_('PartitionLightOutput', AddressableLight)
MakePartitionLight = Application.struct('MakePartitionLight')
def validate_from_to(value):
if value[CONF_FROM] > value[CONF_TO]:
raise vol.Invalid(u"From ({}) must not be larger than to ({})"
u"".format(value[CONF_FROM], value[CONF_TO]))
return value
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(light.AddressableLightState),
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakePartitionLight),
vol.Required(CONF_SEGMENTS): vol.All(cv.ensure_list({
vol.Required(CONF_ID): cv.use_variable_id(light.AddressableLightState),
vol.Required(CONF_FROM): cv.positive_int,
vol.Required(CONF_TO): cv.positive_int,
}, validate_from_to), vol.Length(min=1)),
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
vol.Optional(CONF_EFFECTS): light.validate_effects(light.ADDRESSABLE_EFFECTS),
}))
def to_code(config):
segments = []
for conf in config[CONF_SEGMENTS]:
for var in get_variable(conf[CONF_ID]):
yield
segments.append(AddressableSegment(var, conf[CONF_FROM],
conf[CONF_TO] - conf[CONF_FROM] + 1))
rhs = App.make_partition_light(config[CONF_NAME], segments)
make = variable(config[CONF_MAKE_ID], rhs)
light.setup_light(make.Pstate, config)
def to_hass_config(data, config):
return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False)

View File

@@ -1,58 +0,0 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_STATE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Action, App, float_, optional
TemplateSensor = sensor.sensor_ns.class_('TemplateSensor', sensor.PollingSensorComponent)
SensorPublishAction = sensor.sensor_ns.class_('SensorPublishAction', Action)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateSensor),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
template = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(template, config)
setup_component(template, config)
if CONF_LAMBDA in config:
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(float_)):
yield
add(template.set_template(template_))
BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR'
CONF_SENSOR_TEMPLATE_PUBLISH = 'sensor.template.publish'
SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
vol.Required(CONF_ID): cv.use_variable_id(sensor.Sensor),
vol.Required(CONF_STATE): cv.templatable(cv.float_),
})
@ACTION_REGISTRY.register(CONF_SENSOR_TEMPLATE_PUBLISH, SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA)
def sensor_template_publish_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
rhs = var.make_sensor_publish_action(template_arg)
type = SensorPublishAction.template(arg_type)
action = Pvariable(action_id, rhs, type=type)
for template_ in templatable(config[CONF_STATE], arg_type, float_):
yield None
add(action.set_state(template_))
yield action
def to_hass_config(data, config):
return sensor.core_to_hass_config(data, config)

View File

@@ -1,78 +0,0 @@
import voluptuous as vol
from esphome import automation
from esphome.automation import ACTION_REGISTRY
from esphome.components import switch
import esphome.config_validation as cv
from esphome.const import CONF_ASSUMED_STATE, CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_OPTIMISTIC, \
CONF_RESTORE_STATE, CONF_STATE, CONF_TURN_OFF_ACTION, CONF_TURN_ON_ACTION
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Action, App, Component, NoArg, bool_, optional
TemplateSwitch = switch.switch_ns.class_('TemplateSwitch', switch.Switch, Component)
SwitchPublishAction = switch.switch_ns.class_('SwitchPublishAction', Action)
PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateSwitch),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_ASSUMED_STATE): cv.boolean,
vol.Optional(CONF_TURN_OFF_ACTION): automation.validate_automation(single=True),
vol.Optional(CONF_TURN_ON_ACTION): automation.validate_automation(single=True),
vol.Optional(CONF_RESTORE_STATE): cv.boolean,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_switch(config[CONF_NAME])
template = Pvariable(config[CONF_ID], rhs)
switch.setup_switch(template, config)
if CONF_LAMBDA in config:
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(bool_)):
yield
add(template.set_state_lambda(template_))
if CONF_TURN_OFF_ACTION in config:
automation.build_automation(template.get_turn_off_trigger(), NoArg,
config[CONF_TURN_OFF_ACTION])
if CONF_TURN_ON_ACTION in config:
automation.build_automation(template.get_turn_on_trigger(), NoArg,
config[CONF_TURN_ON_ACTION])
if CONF_OPTIMISTIC in config:
add(template.set_optimistic(config[CONF_OPTIMISTIC]))
if CONF_ASSUMED_STATE in config:
add(template.set_assumed_state(config[CONF_ASSUMED_STATE]))
if CONF_RESTORE_STATE in config:
add(template.set_restore_state(config[CONF_RESTORE_STATE]))
setup_component(template, config)
BUILD_FLAGS = '-DUSE_TEMPLATE_SWITCH'
CONF_SWITCH_TEMPLATE_PUBLISH = 'switch.template.publish'
SWITCH_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
vol.Required(CONF_ID): cv.use_variable_id(switch.Switch),
vol.Required(CONF_STATE): cv.templatable(cv.boolean),
})
@ACTION_REGISTRY.register(CONF_SWITCH_TEMPLATE_PUBLISH, SWITCH_TEMPLATE_PUBLISH_ACTION_SCHEMA)
def switch_template_publish_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
rhs = var.make_switch_publish_action(template_arg)
type = SwitchPublishAction.template(arg_type)
action = Pvariable(action_id, rhs, type=type)
for template_ in templatable(config[CONF_STATE], arg_type, bool_):
yield None
add(action.set_state(template_))
yield action
def to_hass_config(data, config):
return switch.core_to_hass_config(data, config)

View File

@@ -1,59 +0,0 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY
from esphome.components import text_sensor
from esphome.components.text_sensor import TextSensorPublishAction
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_STATE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent, optional, std_string
TemplateTextSensor = text_sensor.text_sensor_ns.class_('TemplateTextSensor',
text_sensor.TextSensor, PollingComponent)
PLATFORM_SCHEMA = cv.nameable(text_sensor.TEXT_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateTextSensor),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_text_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
template = Pvariable(config[CONF_ID], rhs)
text_sensor.setup_text_sensor(template, config)
setup_component(template, config)
if CONF_LAMBDA in config:
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(std_string)):
yield
add(template.set_template(template_))
BUILD_FLAGS = '-DUSE_TEMPLATE_TEXT_SENSOR'
CONF_TEXT_SENSOR_TEMPLATE_PUBLISH = 'text_sensor.template.publish'
TEXT_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = vol.Schema({
vol.Required(CONF_ID): cv.use_variable_id(text_sensor.TextSensor),
vol.Required(CONF_STATE): cv.templatable(cv.string_strict),
})
@ACTION_REGISTRY.register(CONF_TEXT_SENSOR_TEMPLATE_PUBLISH,
TEXT_SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA)
def text_sensor_template_publish_to_code(config, action_id, arg_type, template_arg):
for var in get_variable(config[CONF_ID]):
yield None
rhs = var.make_text_sensor_publish_action(template_arg)
type = TextSensorPublishAction.template(arg_type)
action = Pvariable(action_id, rhs, type=type)
for template_ in templatable(config[CONF_STATE], arg_type, std_string):
yield None
add(action.set_state(template_))
yield action
def to_hass_config(data, config):
return text_sensor.core_to_hass_config(data, config)

View File

@@ -1,27 +0,0 @@
from esphome.components import text_sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
VersionTextSensor = text_sensor.text_sensor_ns.class_('VersionTextSensor',
text_sensor.TextSensor, Component)
PLATFORM_SCHEMA = cv.nameable(text_sensor.TEXT_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(VersionTextSensor),
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_version_text_sensor(config[CONF_NAME])
sens = Pvariable(config[CONF_ID], rhs)
text_sensor.setup_text_sensor(sens, config)
setup_component(sens, config)
BUILD_FLAGS = '-DUSE_VERSION_TEXT_SENSOR'
def to_hass_config(data, config):
return text_sensor.core_to_hass_config(data, config)

View File

@@ -1,34 +0,0 @@
import voluptuous as vol
from esphome import pins
import esphome.config_validation as cv
from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component, esphome_ns
UARTComponent = esphome_ns.class_('UARTComponent', Component)
UARTDevice = esphome_ns.class_('UARTDevice')
MULTI_CONF = True
CONFIG_SCHEMA = vol.All(vol.Schema({
cv.GenerateID(): cv.declare_variable_id(UARTComponent),
vol.Optional(CONF_TX_PIN): pins.output_pin,
vol.Optional(CONF_RX_PIN): pins.input_pin,
vol.Required(CONF_BAUD_RATE): cv.positive_int,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_TX_PIN, CONF_RX_PIN))
def to_code(config):
rhs = App.init_uart(config[CONF_BAUD_RATE])
var = Pvariable(config[CONF_ID], rhs)
if CONF_TX_PIN in config:
add(var.set_tx_pin(config[CONF_TX_PIN]))
if CONF_RX_PIN in config:
add(var.set_rx_pin(config[CONF_RX_PIN]))
setup_component(var, config)
BUILD_FLAGS = '-DUSE_UART'

View File

@@ -1,37 +0,0 @@
from esphome.cpp_generator import MockObj
global_ns = MockObj('', '')
void = global_ns.namespace('void')
float_ = global_ns.namespace('float')
bool_ = global_ns.namespace('bool')
std_ns = global_ns.namespace('std')
std_string = std_ns.class_('string')
std_vector = std_ns.class_('vector')
uint8 = global_ns.namespace('uint8_t')
uint16 = global_ns.namespace('uint16_t')
uint32 = global_ns.namespace('uint32_t')
int32 = global_ns.namespace('int32_t')
const_char_ptr = global_ns.namespace('const char *')
NAN = global_ns.namespace('NAN')
esphome_ns = global_ns # using namespace esphome;
NoArg = esphome_ns.class_('NoArg')
App = esphome_ns.App
io_ns = esphome_ns.namespace('io')
Nameable = esphome_ns.class_('Nameable')
Trigger = esphome_ns.class_('Trigger')
Action = esphome_ns.class_('Action')
Component = esphome_ns.class_('Component')
ComponentPtr = Component.operator('ptr')
PollingComponent = esphome_ns.class_('PollingComponent', Component)
Application = esphome_ns.class_('Application')
optional = esphome_ns.class_('optional')
arduino_json_ns = global_ns.namespace('ArduinoJson')
JsonObject = arduino_json_ns.class_('JsonObject')
JsonObjectRef = JsonObject.operator('ref')
JsonObjectConstRef = JsonObjectRef.operator('const')
Controller = esphome_ns.class_('Controller')
StoringController = esphome_ns.class_('StoringController', Controller)
GPIOPin = esphome_ns.class_('GPIOPin')
GPIOOutputPin = esphome_ns.class_('GPIOOutputPin', GPIOPin)
GPIOInputPin = esphome_ns.class_('GPIOInputPin', GPIOPin)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,13 +0,0 @@
from __future__ import print_function
import sys
def main():
print("The esphomeyaml command has been renamed to esphome.")
print("")
print("$ esphome {}".format(' '.join(sys.argv[1:])))
return 1
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1,780 +0,0 @@
# Custom zeroconf implementation based on python-zeroconf
# (https://github.com/jstasiak/python-zeroconf) that supports Python 2
import errno
import logging
import select
import socket
import struct
import sys
import threading
import time
import ifaddr
from esphome.py_compat import indexbytes, text_type
log = logging.getLogger(__name__)
# Some timing constants
_LISTENER_TIME = 200
# Some DNS constants
_MDNS_ADDR = '224.0.0.251'
_MDNS_PORT = 5353
_MAX_MSG_ABSOLUTE = 8966
_FLAGS_QR_MASK = 0x8000 # query response mask
_FLAGS_QR_QUERY = 0x0000 # query
_FLAGS_QR_RESPONSE = 0x8000 # response
_FLAGS_AA = 0x0400 # Authoritative answer
_FLAGS_TC = 0x0200 # Truncated
_FLAGS_RD = 0x0100 # Recursion desired
_FLAGS_RA = 0x8000 # Recursion available
_FLAGS_Z = 0x0040 # Zero
_FLAGS_AD = 0x0020 # Authentic data
_FLAGS_CD = 0x0010 # Checking disabled
_CLASS_IN = 1
_CLASS_CS = 2
_CLASS_CH = 3
_CLASS_HS = 4
_CLASS_NONE = 254
_CLASS_ANY = 255
_CLASS_MASK = 0x7FFF
_CLASS_UNIQUE = 0x8000
_TYPE_A = 1
_TYPE_NS = 2
_TYPE_MD = 3
_TYPE_MF = 4
_TYPE_CNAME = 5
_TYPE_SOA = 6
_TYPE_MB = 7
_TYPE_MG = 8
_TYPE_MR = 9
_TYPE_NULL = 10
_TYPE_WKS = 11
_TYPE_PTR = 12
_TYPE_HINFO = 13
_TYPE_MINFO = 14
_TYPE_MX = 15
_TYPE_TXT = 16
_TYPE_AAAA = 28
_TYPE_SRV = 33
_TYPE_ANY = 255
# Mapping constants to names
int2byte = struct.Struct(">B").pack
# Exceptions
class Error(Exception):
pass
class IncomingDecodeError(Error):
pass
# pylint: disable=no-init
class QuietLogger(object):
_seen_logs = {}
@classmethod
def log_exception_warning(cls, logger_data=None):
exc_info = sys.exc_info()
exc_str = str(exc_info[1])
if exc_str not in cls._seen_logs:
# log at warning level the first time this is seen
cls._seen_logs[exc_str] = exc_info
logger = log.warning
else:
logger = log.debug
if logger_data is not None:
logger(*logger_data)
logger('Exception occurred:', exc_info=True)
@classmethod
def log_warning_once(cls, *args):
msg_str = args[0]
if msg_str not in cls._seen_logs:
cls._seen_logs[msg_str] = 0
logger = log.warning
else:
logger = log.debug
cls._seen_logs[msg_str] += 1
logger(*args)
class DNSEntry(object):
"""A DNS entry"""
def __init__(self, name, type_, class_):
self.key = name.lower()
self.name = name
self.type = type_
self.class_ = class_ & _CLASS_MASK
self.unique = (class_ & _CLASS_UNIQUE) != 0
class DNSQuestion(DNSEntry):
"""A DNS question entry"""
def __init__(self, name, type_, class_):
DNSEntry.__init__(self, name, type_, class_)
def answered_by(self, rec):
"""Returns true if the question is answered by the record"""
return (self.class_ == rec.class_ and
(self.type == rec.type or self.type == _TYPE_ANY) and
self.name == rec.name)
class DNSRecord(DNSEntry):
"""A DNS record - like a DNS entry, but has a TTL"""
def __init__(self, name, type_, class_, ttl):
DNSEntry.__init__(self, name, type_, class_)
self.ttl = 15
self.created = time.time()
def write(self, out):
"""Abstract method"""
raise NotImplementedError
def is_expired(self, now):
return self.created + self.ttl <= now
def is_removable(self, now):
return self.created + self.ttl * 2 <= now
class DNSAddress(DNSRecord):
"""A DNS address record"""
def __init__(self, name, type_, class_, ttl, address):
DNSRecord.__init__(self, name, type_, class_, ttl)
self.address = address
def write(self, out):
"""Used in constructing an outgoing packet"""
out.write_string(self.address)
class DNSText(DNSRecord):
"""A DNS text record"""
def __init__(self, name, type_, class_, ttl, text):
assert isinstance(text, (bytes, type(None)))
DNSRecord.__init__(self, name, type_, class_, ttl)
self.text = text
def write(self, out):
"""Used in constructing an outgoing packet"""
out.write_string(self.text)
class DNSIncoming(QuietLogger):
"""Object representation of an incoming DNS packet"""
def __init__(self, data):
"""Constructor from string holding bytes of packet"""
self.offset = 0
self.data = data
self.questions = []
self.answers = []
self.id = 0
self.flags = 0 # type: int
self.num_questions = 0
self.num_answers = 0
self.num_authorities = 0
self.num_additionals = 0
self.valid = False
try:
self.read_header()
self.read_questions()
self.read_others()
self.valid = True
except (IndexError, struct.error, IncomingDecodeError):
self.log_exception_warning((
'Choked at offset %d while unpacking %r', self.offset, data))
def unpack(self, format_):
length = struct.calcsize(format_)
info = struct.unpack(
format_, self.data[self.offset:self.offset + length])
self.offset += length
return info
def read_header(self):
"""Reads header portion of packet"""
(self.id, self.flags, self.num_questions, self.num_answers,
self.num_authorities, self.num_additionals) = self.unpack(b'!6H')
def read_questions(self):
"""Reads questions section of packet"""
for _ in range(self.num_questions):
name = self.read_name()
type_, class_ = self.unpack(b'!HH')
question = DNSQuestion(name, type_, class_)
self.questions.append(question)
def read_character_string(self):
"""Reads a character string from the packet"""
length = self.data[self.offset]
self.offset += 1
return self.read_string(length)
def read_string(self, length):
"""Reads a string of a given length from the packet"""
info = self.data[self.offset:self.offset + length]
self.offset += length
return info
def read_unsigned_short(self):
"""Reads an unsigned short from the packet"""
return self.unpack(b'!H')[0]
def read_others(self):
"""Reads the answers, authorities and additionals section of the
packet"""
n = self.num_answers + self.num_authorities + self.num_additionals
for _ in range(n):
domain = self.read_name()
type_, class_, ttl, length = self.unpack(b'!HHiH')
rec = None
if type_ == _TYPE_A:
rec = DNSAddress(
domain, type_, class_, ttl, self.read_string(4))
elif type_ == _TYPE_TXT:
rec = DNSText(
domain, type_, class_, ttl, self.read_string(length))
elif type_ == _TYPE_AAAA:
rec = DNSAddress(
domain, type_, class_, ttl, self.read_string(16))
else:
# Try to ignore types we don't know about
# Skip the payload for the resource record so the next
# records can be parsed correctly
self.offset += length
if rec is not None:
self.answers.append(rec)
def is_query(self):
"""Returns true if this is a query"""
return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
def is_response(self):
"""Returns true if this is a response"""
return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_RESPONSE
def read_utf(self, offset, length):
"""Reads a UTF-8 string of a given length from the packet"""
return text_type(self.data[offset:offset + length], 'utf-8', 'replace')
def read_name(self):
"""Reads a domain name from the packet"""
result = ''
off = self.offset
next_ = -1
first = off
while True:
length = indexbytes(self.data, off)
off += 1
if length == 0:
break
t = length & 0xC0
if t == 0x00:
result = ''.join((result, self.read_utf(off, length) + '.'))
off += length
elif t == 0xC0:
if next_ < 0:
next_ = off + 1
off = ((length & 0x3F) << 8) | indexbytes(self.data, off)
if off >= first:
raise IncomingDecodeError(
"Bad domain name (circular) at %s" % (off,))
first = off
else:
raise IncomingDecodeError("Bad domain name at %s" % (off,))
if next_ >= 0:
self.offset = next_
else:
self.offset = off
return result
class DNSOutgoing(object):
"""Object representation of an outgoing packet"""
def __init__(self, flags):
self.finished = False
self.id = 0
self.flags = flags
self.names = {}
self.data = []
self.size = 12
self.state = False
self.questions = []
self.answers = []
def add_question(self, record):
"""Adds a question"""
self.questions.append(record)
def pack(self, format_, value):
self.data.append(struct.pack(format_, value))
self.size += struct.calcsize(format_)
def write_byte(self, value):
"""Writes a single byte to the packet"""
self.pack(b'!c', int2byte(value))
def insert_short(self, index, value):
"""Inserts an unsigned short in a certain position in the packet"""
self.data.insert(index, struct.pack(b'!H', value))
self.size += 2
def write_short(self, value):
"""Writes an unsigned short to the packet"""
self.pack(b'!H', value)
def write_int(self, value):
"""Writes an unsigned integer to the packet"""
self.pack(b'!I', int(value))
def write_string(self, value):
"""Writes a string to the packet"""
assert isinstance(value, bytes)
self.data.append(value)
self.size += len(value)
def write_utf(self, s):
"""Writes a UTF-8 string of a given length to the packet"""
utfstr = s.encode('utf-8')
length = len(utfstr)
self.write_byte(length)
self.write_string(utfstr)
def write_character_string(self, value):
assert isinstance(value, bytes)
length = len(value)
self.write_byte(length)
self.write_string(value)
def write_name(self, name):
# split name into each label
parts = name.split('.')
if not parts[-1]:
parts.pop()
# construct each suffix
name_suffices = ['.'.join(parts[i:]) for i in range(len(parts))]
# look for an existing name or suffix
for count, sub_name in enumerate(name_suffices):
if sub_name in self.names:
break
else:
count = len(name_suffices)
# note the new names we are saving into the packet
name_length = len(name.encode('utf-8'))
for suffix in name_suffices[:count]:
self.names[suffix] = self.size + name_length - len(suffix.encode('utf-8')) - 1
# write the new names out.
for part in parts[:count]:
self.write_utf(part)
# if we wrote part of the name, create a pointer to the rest
if count != len(name_suffices):
# Found substring in packet, create pointer
index = self.names[name_suffices[count]]
self.write_byte((index >> 8) | 0xC0)
self.write_byte(index & 0xFF)
else:
# this is the end of a name
self.write_byte(0)
def write_question(self, question):
self.write_name(question.name)
self.write_short(question.type)
self.write_short(question.class_)
def packet(self):
if not self.state:
for question in self.questions:
self.write_question(question)
self.state = True
self.insert_short(0, 0) # num additionals
self.insert_short(0, 0) # num authorities
self.insert_short(0, 0) # num answers
self.insert_short(0, len(self.questions))
self.insert_short(0, self.flags) # _FLAGS_QR_QUERY
self.insert_short(0, 0)
return b''.join(self.data)
class Engine(threading.Thread):
def __init__(self, zc):
threading.Thread.__init__(self, name='zeroconf-Engine')
self.daemon = True
self.zc = zc
self.readers = {}
self.timeout = 5
self.condition = threading.Condition()
self.start()
def run(self):
while not self.zc.done:
# pylint: disable=len-as-condition
with self.condition:
rs = self.readers.keys()
if len(rs) == 0:
# No sockets to manage, but we wait for the timeout
# or addition of a socket
self.condition.wait(self.timeout)
if len(rs) != 0:
try:
rr, _, _ = select.select(rs, [], [], self.timeout)
if not self.zc.done:
for socket_ in rr:
reader = self.readers.get(socket_)
if reader:
reader.handle_read(socket_)
except (select.error, socket.error) as e:
# If the socket was closed by another thread, during
# shutdown, ignore it and exit
if e.args[0] != socket.EBADF or not self.zc.done:
raise
def add_reader(self, reader, socket_):
with self.condition:
self.readers[socket_] = reader
self.condition.notify()
def del_reader(self, socket_):
with self.condition:
del self.readers[socket_]
self.condition.notify()
class Listener(QuietLogger):
def __init__(self, zc):
self.zc = zc
self.data = None
def handle_read(self, socket_):
try:
data, (addr, port) = socket_.recvfrom(_MAX_MSG_ABSOLUTE)
except Exception: # pylint: disable=broad-except
self.log_exception_warning()
return
log.debug('Received from %r:%r: %r ', addr, port, data)
self.data = data
msg = DNSIncoming(data)
if not msg.valid or msg.is_query():
pass
else:
self.zc.handle_response(msg)
class RecordUpdateListener(object):
def update_record(self, zc, now, record):
raise NotImplementedError()
class HostResolver(RecordUpdateListener):
def __init__(self, name):
self.name = name
self.address = None
def update_record(self, zc, now, record):
if record is None:
return
if record.type == _TYPE_A:
assert isinstance(record, DNSAddress)
if record.name == self.name:
self.address = record.address
def request(self, zc, timeout):
now = time.time()
delay = 0.2
next_ = now + delay
last = now + timeout
try:
zc.add_listener(self)
while self.address is None:
if last <= now:
# Timeout
return False
if next_ <= now:
out = DNSOutgoing(_FLAGS_QR_QUERY)
out.add_question(
DNSQuestion(self.name, _TYPE_A, _CLASS_IN))
zc.send(out)
next_ = now + delay
delay *= 2
zc.wait(min(next_, last) - now)
now = time.time()
finally:
zc.remove_listener(self)
return True
class DashboardStatus(RecordUpdateListener, threading.Thread):
def __init__(self, zc, on_update):
threading.Thread.__init__(self)
self.zc = zc
self.query_hosts = set()
self.key_to_host = {}
self.cache = {}
self.stop_event = threading.Event()
self.query_event = threading.Event()
self.on_update = on_update
def update_record(self, zc, now, record):
if record is None:
return
if record.type in (_TYPE_A, _TYPE_AAAA, _TYPE_TXT):
assert isinstance(record, DNSEntry)
if record.name in self.query_hosts:
self.cache.setdefault(record.name, []).insert(0, record)
self.purge_cache()
def purge_cache(self):
new_cache = {}
for host, records in self.cache.items():
if host not in self.query_hosts:
continue
new_records = [rec for rec in records if not rec.is_removable(time.time())]
if new_records:
new_cache[host] = new_records
self.cache = new_cache
self.on_update({key: self.host_status(key) for key in self.key_to_host})
def request_query(self, hosts):
self.query_hosts = set(host for host in hosts.values())
self.key_to_host = hosts
self.query_event.set()
def stop(self):
self.stop_event.set()
self.query_event.set()
def host_status(self, key):
return self.key_to_host.get(key) in self.cache
def run(self):
self.zc.add_listener(self)
while not self.stop_event.is_set():
self.purge_cache()
for host in self.query_hosts:
if all(record.is_expired(time.time()) for record in self.cache.get(host, [])):
out = DNSOutgoing(_FLAGS_QR_QUERY)
out.add_question(
DNSQuestion(host, _TYPE_A, _CLASS_IN))
self.zc.send(out)
self.query_event.wait()
self.query_event.clear()
self.zc.remove_listener(self)
def get_all_addresses():
return list(set(
addr.ip
for iface in ifaddr.get_adapters()
for addr in iface.ips
if addr.is_IPv4 and addr.network_prefix != 32 # Host only netmask 255.255.255.255
))
def new_socket():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# SO_REUSEADDR should be equivalent to SO_REUSEPORT for
# multicast UDP sockets (p 731, "TCP/IP Illustrated,
# Volume 2"), but some BSD-derived systems require
# SO_REUSEPORT to be specified explicitly. Also, not all
# versions of Python have SO_REUSEPORT available.
# Catch OSError and socket.error for kernel versions <3.9 because lacking
# SO_REUSEPORT support.
try:
reuseport = socket.SO_REUSEPORT
except AttributeError:
pass
else:
try:
s.setsockopt(socket.SOL_SOCKET, reuseport, 1)
except (OSError, socket.error) as err:
# OSError on python 3, socket.error on python 2
if err.errno != errno.ENOPROTOOPT:
raise
# OpenBSD needs the ttl and loop values for the IP_MULTICAST_TTL and
# IP_MULTICAST_LOOP socket options as an unsigned char.
ttl = struct.pack(b'B', 255)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
loop = struct.pack(b'B', 1)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop)
s.bind(('', _MDNS_PORT))
return s
class Zeroconf(QuietLogger):
def __init__(self):
# hook for threads
self._GLOBAL_DONE = False
self._listen_socket = new_socket()
interfaces = get_all_addresses()
self._respond_sockets = []
for i in interfaces:
try:
_value = socket.inet_aton(_MDNS_ADDR) + socket.inet_aton(i)
self._listen_socket.setsockopt(
socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, _value)
except socket.error as e:
_errno = e.args[0]
if _errno == errno.EADDRINUSE:
log.info(
'Address in use when adding %s to multicast group, '
'it is expected to happen on some systems', i,
)
elif _errno == errno.EADDRNOTAVAIL:
log.info(
'Address not available when adding %s to multicast '
'group, it is expected to happen on some systems', i,
)
continue
elif _errno == errno.EINVAL:
log.info(
'Interface of %s does not support multicast, '
'it is expected in WSL', i
)
continue
else:
raise
respond_socket = new_socket()
respond_socket.setsockopt(
socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(i))
self._respond_sockets.append(respond_socket)
self.listeners = []
self.condition = threading.Condition()
self.engine = Engine(self)
self.listener = Listener(self)
self.engine.add_reader(self.listener, self._listen_socket)
@property
def done(self):
return self._GLOBAL_DONE
def wait(self, timeout):
"""Calling thread waits for a given number of milliseconds or
until notified."""
with self.condition:
self.condition.wait(timeout)
def notify_all(self):
"""Notifies all waiting threads"""
with self.condition:
self.condition.notify_all()
def resolve_host(self, host, timeout=3.0):
info = HostResolver(host)
if info.request(self, timeout):
return socket.inet_ntoa(info.address)
return None
def add_listener(self, listener):
self.listeners.append(listener)
self.notify_all()
def remove_listener(self, listener):
"""Removes a listener."""
try:
self.listeners.remove(listener)
self.notify_all()
except Exception as e: # pylint: disable=broad-except
log.exception('Unknown error, possibly benign: %r', e)
def update_record(self, now, rec):
"""Used to notify listeners of new information that has updated
a record."""
for listener in self.listeners:
listener.update_record(self, now, rec)
self.notify_all()
def handle_response(self, msg):
"""Deal with incoming response packets. All answers
are held in the cache, and listeners are notified."""
now = time.time()
for record in msg.answers:
self.update_record(now, record)
def send(self, out):
"""Sends an outgoing packet."""
packet = out.packet()
log.debug('Sending %r (%d bytes) as %r...', out, len(packet), packet)
for s in self._respond_sockets:
if self._GLOBAL_DONE:
return
try:
bytes_sent = s.sendto(packet, 0, (_MDNS_ADDR, _MDNS_PORT))
except Exception: # pylint: disable=broad-except
# on send errors, log the exception and keep going
self.log_exception_warning()
else:
if bytes_sent != len(packet):
self.log_warning_once(
'!!! sent %d out of %d bytes to %r' % (
bytes_sent, len(packet), s))
def close(self):
"""Ends the background threads, and prevent this instance from
servicing further queries."""
if not self._GLOBAL_DONE:
self._GLOBAL_DONE = True
# shutdown recv socket and thread
self.engine.del_reader(self._listen_socket)
self._listen_socket.close()
self.engine.join()
# shutdown the rest
self.notify_all()
for s in self._respond_sockets:
s.close()

View File

@@ -35,6 +35,5 @@
"port": "int",
"leave_front_door_open": "bool?",
"esphomeyaml_version": "str?"
},
"image": "ottowinter/esphomeyaml-hassio-{arch}"
}
}

View File

@@ -1,4 +1,4 @@
ARG BUILD_FROM=hassioaddons/ubuntu-base:2.2.1
ARG BUILD_FROM=hassioaddons/ubuntu-base:2.2.0
# hadolint ignore=DL3006
FROM ${BUILD_FROM}
@@ -14,7 +14,7 @@ RUN \
# Install add-on dependencies
&& apt-get update \
&& apt-get install -y --no-install-recommends \
# Python 2 for ESPHome
# Python for esphomeyaml
python \
python-pip \
python-setuptools \
@@ -22,12 +22,14 @@ RUN \
python-pil \
# Git for esphomelib downloads
git \
# 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/esphome/esphome/archive/dev.zip \
&& pip2 install --no-cache-dir --no-binary :all: https://github.com/OttoWinter/esphomeyaml/archive/dev.zip \
\
# Change some platformio settings
&& platformio settings set enable_telemetry No \
@@ -48,12 +50,24 @@ RUN \
# Build arugments
ARG BUILD_ARCH=amd64
ARG BUILD_DATE
ARG BUILD_REF
ARG BUILD_VERSION
# Labels
LABEL \
io.hass.name="ESPHome" \
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}
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"

View File

@@ -1,10 +1,10 @@
{
"squash": false,
"build_from": {
"aarch64": "hassioaddons/ubuntu-base-aarch64:2.2.1",
"amd64": "hassioaddons/ubuntu-base-amd64:2.2.1",
"armhf": "hassioaddons/ubuntu-base-armhf:2.2.1",
"i386": "hassioaddons/ubuntu-base-i386:2.2.1"
"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": {}
}

View File

@@ -7,6 +7,7 @@
"webui": "http://[HOST]:[PORT:6052]",
"startup": "application",
"arch": [
"aarch64",
"amd64",
"armhf",
"i386"
@@ -26,8 +27,7 @@
"ssl": false,
"certfile": "fullchain.pem",
"keyfile": "privkey.pem",
"port": 6052,
"esphome_version": "dev"
"port": 6052
},
"schema": {
"ssl": "bool",
@@ -35,6 +35,6 @@
"keyfile": "str",
"port": "int",
"leave_front_door_open": "bool?",
"esphome_version": "str?"
"esphomeyaml_version": "str?"
}
}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Community Hass.io Add-ons: esphomeyaml
# This files check if all user configuration requirements are met
# ==============================================================================
# shellcheck disable=SC1091
@@ -22,7 +22,7 @@ if hass.config.true 'ssl'; then
text="You enabled encrypted connections using the \"ssl\": true option.
However, the SSL files \"$(hass.config.get 'certfile')\" and \"$(hass.config.get 'keyfile')\"
were not found. If you're using Hass.io on your local network and don't want
to encrypt connections to the ESPHome dashboard, you can manually disable
to encrypt connections to the esphomeyaml dashboard, you can manually disable
SSL by setting \"ssl\" to false."
hass.die "${text}"
fi

View File

@@ -1,7 +1,7 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Configures NGINX for use with ESPHome
# Community Hass.io Add-ons: esphomeyaml
# Configures NGINX for use with esphomeyaml
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh

View File

@@ -1,14 +1,14 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files installs the user ESPHome version if specified
# Community Hass.io Add-ons: esphomeyaml
# This files installs the user esphomeyaml version if specified
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
declare esphome_version
declare esphomeyaml_version
if hass.config.has_value 'esphome_version'; then
esphome_version=$(hass.config.get 'esphome_version')
pip2 install --no-cache-dir --no-binary :all: "https://github.com/esphome/esphome/archive/${esphome_version}.zip"
if hass.config.has_value 'esphomeyaml_version'; then
esphomeyaml_version=$(hass.config.get 'esphomeyaml_version')
pip2 install --no-cache-dir --no-binary :all: "https://github.com/OttoWinter/esphomeyaml/archive/${esphomeyaml_version}.zip"
fi

View File

@@ -1,13 +0,0 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files migrates the esphome config directory from the old path
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
if [[ ! -d /config/esphome && -d /config/esphomeyaml ]]; then
echo "Moving config directory from /config/esphomeyaml to /config/esphome"
mv /config/esphomeyaml /config/esphome
mv /config/esphome/.esphomeyaml /config/esphome/.esphome
fi

View File

@@ -13,9 +13,9 @@ http {
sendfile on;
keepalive_timeout 65;
upstream esphome {
upstream esphomeyaml {
ip_hash;
server unix:/var/run/esphome.sock;
server unix:/var/run/esphomeyaml.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
@@ -45,7 +45,7 @@ http {
location / {
proxy_redirect off;
proxy_pass http://esphome;
proxy_pass http://esphomeyaml;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;

View File

@@ -13,9 +13,9 @@ http {
sendfile on;
keepalive_timeout 65;
upstream esphome {
upstream esphomeyaml {
ip_hash;
server unix:/var/run/esphome.sock;
server unix:/var/run/esphomeyaml.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
@@ -29,7 +29,7 @@ http {
location / {
proxy_redirect off;
proxy_pass http://esphome;
proxy_pass http://esphomeyaml;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;

View File

@@ -1,9 +0,0 @@
#!/usr/bin/execlineb -S0
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Take down the S6 supervision tree when ESPHome fails
# ==============================================================================
if -n { s6-test $# -ne 0 }
if -n { s6-test ${1} -eq 256 }
s6-svscanctl -t /var/run/s6/services

View File

@@ -1,7 +1,7 @@
#!/usr/bin/execlineb -S0
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Take down the S6 supervision tree when ESPHome fails
# 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 }

View File

@@ -1,7 +1,7 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Runs the ESPHome dashboard
# Community Hass.io Add-ons: esphomeyaml
# Runs the esphomeyaml dashboard
# ==============================================================================
# shellcheck disable=SC1091
source /usr/lib/hassio-addons/base.sh
@@ -10,5 +10,5 @@ if hass.config.true 'leave_front_door_open'; then
export DISABLE_HA_AUTHENTICATION=true
fi
hass.log.info "Starting ESPHome dashboard..."
exec esphome /config/esphome dashboard --socket /var/run/esphome.sock --hassio
hass.log.info "Starting esphomeyaml dashboard..."
exec esphomeyaml /config/esphomeyaml dashboard --socket /var/run/esphomeyaml.sock --hassio

View File

@@ -1,6 +1,6 @@
#!/usr/bin/execlineb -S0
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Community Hass.io Add-ons: esphomeyaml
# Take down the S6 supervision tree when NGINX fails
# ==============================================================================
if -n { s6-test $# -ne 0 }

View File

@@ -1,6 +1,6 @@
#!/usr/bin/with-contenv bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Community Hass.io Add-ons: esphomeyaml
# Runs the NGINX proxy
# ==============================================================================
# shellcheck disable=SC1091

View File

@@ -8,22 +8,22 @@ import os
import random
import sys
from esphome import const, core_config, mqtt, platformio_api, wizard, writer, yaml_util
from esphome.api.client import run_logs
from esphome.config import get_component, iter_components, read_config, strip_default_ids
from esphome.const import CONF_BAUD_RATE, CONF_BROKER, CONF_ESPHOME, CONF_LOGGER, \
CONF_USE_CUSTOM_CODE
from esphome.core import CORE, EsphomeError
from esphome.cpp_generator import Expression, RawStatement, add, statement
from esphome.helpers import color, indent
from esphome.py_compat import IS_PY2, safe_input, text_type
from esphome.storage_json import StorageJSON, esphome_storage_path, \
from esphomeyaml import const, core_config, mqtt, platformio_api, wizard, writer, yaml_util
from esphomeyaml.api.client import run_logs
from esphomeyaml.config import get_component, iter_components, read_config, strip_default_ids
from esphomeyaml.const import CONF_BAUD_RATE, CONF_ESPHOMEYAML, CONF_LOGGER, CONF_USE_CUSTOM_CODE, \
CONF_BROKER
from esphomeyaml.core import CORE, EsphomeyamlError
from esphomeyaml.cpp_generator import Expression, RawStatement, add, statement
from esphomeyaml.helpers import color, indent
from esphomeyaml.py_compat import safe_input, text_type, IS_PY2
from esphomeyaml.storage_json import StorageJSON, esphomeyaml_storage_path, \
start_update_check_thread, storage_path
from esphome.util import run_external_command, run_external_process, safe_print
from esphomeyaml.util import run_external_command, safe_print
_LOGGER = logging.getLogger(__name__)
PRE_INITIALIZE = ['esphome', 'logger', 'wifi', 'ethernet', 'ota', 'mqtt', 'web_server', 'api',
PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ethernet', 'ota', 'mqtt', 'web_server', 'api',
'i2c']
@@ -127,9 +127,9 @@ def run_miniterm(config, port):
def write_cpp(config):
_LOGGER.info("Generating C++ source...")
CORE.add_job(core_config.to_code, config[CONF_ESPHOME], domain='esphome')
CORE.add_job(core_config.to_code, config[CONF_ESPHOMEYAML], domain='esphomeyaml')
for domain in PRE_INITIALIZE:
if domain == CONF_ESPHOME or domain not in config:
if domain == CONF_ESPHOMEYAML or domain not in config:
continue
CORE.add_job(get_component(domain).to_code, config[domain], domain=domain)
@@ -143,7 +143,7 @@ def write_cpp(config):
add(RawStatement(''))
all_code = []
for exp in CORE.expressions:
if not config[CONF_ESPHOME][CONF_USE_CUSTOM_CODE]:
if not config[CONF_ESPHOMEYAML][CONF_USE_CUSTOM_CODE]:
if isinstance(exp, Expression) and not exp.required:
continue
all_code.append(text_type(statement(exp)))
@@ -157,9 +157,9 @@ def write_cpp(config):
def compile_program(args, config):
_LOGGER.info("Compiling app...")
update_check = not os.getenv('ESPHOME_NO_UPDATE_CHECK', '')
update_check = not os.getenv('ESPHOMEYAML_NO_UPDATE_CHECK', '')
if update_check:
thread = start_update_check_thread(esphome_storage_path(CORE.config_dir))
thread = start_update_check_thread(esphomeyaml_storage_path(CORE.config_dir))
rc = platformio_api.run_compile(config, args.verbose)
if update_check:
thread.join()
@@ -167,16 +167,13 @@ def compile_program(args, config):
def upload_using_esptool(config, port):
import esptool
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]
if os.environ.get('ESPHOME_USE_SUBPROCESS') is None:
import esptool
# pylint: disable=protected-access
return run_external_command(esptool._main, *cmd)
return run_external_process(*cmd)
# pylint: disable=protected-access
return run_external_command(esptool._main, *cmd)
def upload_program(config, args, host):
@@ -186,13 +183,13 @@ def upload_program(config, args, host):
return upload_using_esptool(config, host)
return platformio_api.run_upload(config, args.verbose, host)
from esphome.components import ota
from esphome import espota2
from esphomeyaml.components import ota
from esphomeyaml import espota2
if args.host_port is not None:
host_port = args.host_port
else:
host_port = int(os.getenv('ESPHOME_OTA_HOST_PORT', random.randint(10000, 60000)))
host_port = int(os.getenv('ESPHOMEYAML_OTA_HOST_PORT', random.randint(10000, 60000)))
verbose = args.verbose
remote_port = ota.get_port(config)
@@ -215,7 +212,7 @@ def upload_program(config, args, host):
def show_logs(config, args, port):
if 'logger' not in config:
raise EsphomeError("Logger is not configured!")
raise EsphomeyamlError("Logger is not configured!")
if get_port_type(port) == 'SERIAL':
run_miniterm(config, port)
return 0
@@ -345,7 +342,7 @@ def command_clean(args, config):
def command_hass_config(args, config):
from esphome.components import mqtt as mqtt_component
from esphomeyaml.components import mqtt as mqtt_component
_LOGGER.info("This is what you should put in your Home Assistant YAML configuration.")
_LOGGER.info("Please note this is only necessary if you're not using MQTT discovery.")
@@ -367,7 +364,7 @@ def command_hass_config(args, config):
def command_dashboard(args):
from esphome.dashboard import dashboard
from esphomeyaml.dashboard import dashboard
return dashboard.start_web_server(args)
@@ -392,8 +389,8 @@ POST_CONFIG_ACTIONS = {
def parse_args(argv):
parser = argparse.ArgumentParser(prog='esphome')
parser.add_argument('-v', '--verbose', help="Enable verbose esphome logs.",
parser = argparse.ArgumentParser(prog='esphomeyaml')
parser.add_argument('-v', '--verbose', help="Enable verbose esphomeyaml logs.",
action='store_true')
parser.add_argument('--dashboard', help="Internal flag to set if the command is run from the "
"dashboard.", action='store_true')
@@ -444,11 +441,11 @@ def parse_args(argv):
parser_clean.add_argument('--client-id', help='Manually set the client id.')
subparsers.add_parser('wizard', help="A helpful setup wizard that will guide "
"you through setting up esphome.")
"you through setting up esphomeyaml.")
subparsers.add_parser('mqtt-fingerprint', help="Get the SSL fingerprint from a MQTT broker.")
subparsers.add_parser('version', help="Print the esphome version and exit.")
subparsers.add_parser('version', help="Print the esphomeyaml version and exit.")
subparsers.add_parser('clean', help="Delete all temporary build files.")
@@ -461,7 +458,7 @@ def parse_args(argv):
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 esphome is started as a Hass.io "
help="Internal flag used to tell esphomeyaml is started as a Hass.io "
"add-on.",
action="store_true")
dashboard.add_argument("--socket",
@@ -474,7 +471,7 @@ def parse_args(argv):
return parser.parse_args(argv[1:])
def run_esphome(argv):
def run_esphomeyaml(argv):
args = parse_args(argv)
CORE.dashboard = args.dashboard
@@ -482,7 +479,7 @@ def run_esphome(argv):
if args.command in PRE_CONFIG_ACTIONS:
try:
return PRE_CONFIG_ACTIONS[args.command](args)
except EsphomeError as e:
except EsphomeyamlError as e:
_LOGGER.error(e)
return 1
@@ -496,7 +493,7 @@ def run_esphome(argv):
if args.command in POST_CONFIG_ACTIONS:
try:
return POST_CONFIG_ACTIONS[args.command](args, config)
except EsphomeError as e:
except EsphomeyamlError as e:
_LOGGER.error(e)
return 1
safe_print(u"Unknown command {}".format(args.command))
@@ -505,8 +502,8 @@ def run_esphome(argv):
def main():
try:
return run_esphome(sys.argv)
except EsphomeError as e:
return run_esphomeyaml(sys.argv)
except EsphomeyamlError as e:
_LOGGER.error(e)
return 1
except KeyboardInterrupt:

View File

@@ -92,7 +92,7 @@ message DeviceInfoResponse {
// A string describing the date of compilation, this is generated by the compiler
// and therefore may not be in the same format all the time.
// If the user isn't using esphome, this will also not be set.
// If the user isn't using esphomeyaml, this will also not be set.
string compilation_time = 5;
// The model of the board. For example NodeMCU

View File

@@ -9,18 +9,18 @@ import time
from typing import Optional # noqa
from google.protobuf import message # noqa
from esphome import const
import esphome.api.api_pb2 as pb
from esphome.const import CONF_PASSWORD, CONF_PORT
from esphome.core import EsphomeError
from esphome.helpers import resolve_ip_address, indent, color
from esphome.py_compat import text_type, IS_PY2, byte_to_bytes, char_to_byte, format_bytes
from esphome.util import safe_print
from esphomeyaml import const
import esphomeyaml.api.api_pb2 as pb
from esphomeyaml.const import CONF_PASSWORD, CONF_PORT
from esphomeyaml.core import EsphomeyamlError
from esphomeyaml.helpers import resolve_ip_address, indent, color
from esphomeyaml.py_compat import text_type, IS_PY2, byte_to_bytes, char_to_byte, format_bytes
from esphomeyaml.util import safe_print
_LOGGER = logging.getLogger(__name__)
class APIConnectionError(EsphomeError):
class APIConnectionError(EsphomeyamlError):
pass
@@ -179,11 +179,11 @@ class APIClient(threading.Thread):
try:
ip = resolve_ip_address(self._address)
except EsphomeError as err:
except EsphomeyamlError as err:
_LOGGER.warning("Error resolving IP address of %s. Is it connected to WiFi?",
self._address)
_LOGGER.warning("(If this error persists, please set a static IP address: "
"https://esphome.io/components/wifi.html#manual-ips)")
"https://esphomelib.com/esphomeyaml/components/wifi.html#manual-ips)")
raise APIConnectionError(err)
_LOGGER.info("Connecting to %s:%s (%s)", self._address, self._port, ip)
@@ -200,7 +200,7 @@ class APIClient(threading.Thread):
self._socket_open_event.set()
hello = pb.HelloRequest()
hello.client_info = 'ESPHome v{}'.format(const.__version__)
hello.client_info = 'esphomeyaml v{}'.format(const.__version__)
try:
resp = self._send_message_await_response(hello, pb.HelloResponse)
except APIConnectionError as err:
@@ -423,14 +423,12 @@ def run_logs(config, address):
conf = config['api']
port = conf[CONF_PORT]
password = conf[CONF_PASSWORD]
_LOGGER.info("Starting log output from %s using esphome API", address)
_LOGGER.info("Starting log output from %s using esphomelib API", address)
cli = APIClient(address, port, password)
stopping = False
retry_timer = []
has_connects = []
def try_connect(tries=0, is_disconnect=True):
if stopping:
return
@@ -453,13 +451,8 @@ def run_logs(config, address):
return
wait_time = min(2**tries, 300)
if not has_connects:
_LOGGER.warning(u"Initial connection failed. The ESP might not be connected "
u"to WiFi yet (%s). Re-Trying in %s seconds",
error, wait_time)
else:
_LOGGER.warning(u"Couldn't connect to API (%s). Trying to reconnect in %s seconds",
error, wait_time)
_LOGGER.warning(u"Couldn't connect to API (%s). Trying to reconnect in %s seconds",
error, wait_time)
timer = threading.Timer(wait_time, functools.partial(try_connect, tries + 1, is_disconnect))
timer.start()
retry_timer.append(timer)
@@ -472,6 +465,8 @@ def run_logs(config, address):
'TCP buffer - This is only cosmetic)')
safe_print(time_ + text)
has_connects = []
def on_login():
try:
cli.subscribe_logs(on_log, dump_config=not has_connects)

View File

@@ -2,16 +2,16 @@ import copy
import voluptuous as vol
import esphome.config_validation as cv
from esphome.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \
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, CONF_WHILE, CONF_WAIT_UNTIL
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, TemplateArguments, add, get_variable, \
process_lambda, templatable
from esphome.cpp_types import Action, App, Component, PollingComponent, Trigger, bool_, \
esphome_ns, float_, uint32, void
from esphome.util import ServiceRegistry
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, void, bool_
from esphomeyaml.util import ServiceRegistry
def maybe_simple_id(*validators):
@@ -98,19 +98,18 @@ ACTION_REGISTRY = ServiceRegistry()
CONDITION_REGISTRY = ServiceRegistry()
# pylint: disable=invalid-name
DelayAction = esphome_ns.class_('DelayAction', Action, Component)
LambdaAction = esphome_ns.class_('LambdaAction', Action)
IfAction = esphome_ns.class_('IfAction', Action)
WhileAction = esphome_ns.class_('WhileAction', Action)
WaitUntilAction = esphome_ns.class_('WaitUntilAction', Action, Component)
UpdateComponentAction = esphome_ns.class_('UpdateComponentAction', Action)
Automation = esphome_ns.class_('Automation')
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')
Condition = esphome_ns.class_('Condition')
AndCondition = esphome_ns.class_('AndCondition', Condition)
OrCondition = esphome_ns.class_('OrCondition', Condition)
RangeCondition = esphome_ns.class_('RangeCondition', Condition)
LambdaCondition = esphome_ns.class_('LambdaCondition', Condition)
Condition = esphomelib_ns.class_('Condition')
AndCondition = esphomelib_ns.class_('AndCondition', Condition)
OrCondition = esphomelib_ns.class_('OrCondition', Condition)
RangeCondition = esphomelib_ns.class_('RangeCondition', Condition)
LambdaCondition = esphomelib_ns.class_('LambdaCondition', Condition)
def validate_automation(extra_schema=None, extra_validators=None, single=False):
@@ -126,9 +125,6 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
# First try as a sequence of actions
return [schema({CONF_THEN: value})]
except vol.Invalid as err:
if err.path and err.path[0] == CONF_THEN:
err.path.pop(0)
# Next try as a sequence of automations
try:
return vol.Schema([schema])(value)
@@ -269,29 +265,6 @@ def while_action_to_code(config, action_id, arg_type, template_arg):
yield action
def validate_wait_until(value):
schema = vol.Schema({
vol.Required(CONF_CONDITION): validate_recursive_condition
})
if isinstance(value, dict) and CONF_CONDITION in value:
return schema(value)
return validate_wait_until({CONF_CONDITION: value})
WAIT_UNTIL_ACTION_SCHEMA = validate_wait_until
@ACTION_REGISTRY.register(CONF_WAIT_UNTIL, WAIT_UNTIL_ACTION_SCHEMA)
def wait_until_action_to_code(config, action_id, arg_type, template_arg):
for conditions in build_conditions(config[CONF_CONDITION], arg_type):
yield None
rhs = WaitUntilAction.new(template_arg, conditions)
type = WaitUntilAction.template(template_arg)
action = Pvariable(action_id, rhs, type=type)
add(App.register_component(action))
yield action
LAMBDA_ACTION_SCHEMA = cv.lambda_
@@ -345,10 +318,11 @@ def build_action(full_config, arg_type):
def build_actions(config, arg_type):
actions = []
for conf in config:
action = None
for action in build_action(conf, arg_type):
yield None
actions.append(action)
yield actions
yield ArrayInitializer(*actions, multiline=False)
def build_condition(full_config, arg_type):
@@ -368,7 +342,7 @@ def build_conditions(config, arg_type):
for condition in build_condition(conf, arg_type):
yield None
conditions.append(condition)
yield conditions
yield ArrayInitializer(*conditions, multiline=False)
def build_automation_(trigger, arg_type, config):

View File

@@ -1,11 +1,11 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
from esphomeyaml.components import i2c, sensor
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ADDRESS, CONF_ID
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

View File

@@ -1,11 +1,11 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
from esphomeyaml.components import i2c, sensor
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_UPDATE_INTERVAL
from esphomeyaml.cpp_generator import Pvariable, add
from esphomeyaml.cpp_helpers import setup_component
from esphomeyaml.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
MULTI_CONF = True

View File

@@ -1,15 +1,15 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY
import esphome.config_validation as cv
from esphome.const import CONF_DATA, CONF_DATA_TEMPLATE, CONF_ID, CONF_PASSWORD, CONF_PORT, \
CONF_REBOOT_TIMEOUT, CONF_SERVICE, CONF_VARIABLES
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Action, App, Component, StoringController, esphome_ns
from esphomeyaml.automation import ACTION_REGISTRY
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_DATA, CONF_DATA_TEMPLATE, CONF_ID, CONF_PASSWORD, CONF_PORT, \
CONF_SERVICE, CONF_VARIABLES, CONF_REBOOT_TIMEOUT
from esphomeyaml.core import CORE
from esphomeyaml.cpp_generator import ArrayInitializer, Pvariable, add, get_variable, process_lambda
from esphomeyaml.cpp_helpers import setup_component
from esphomeyaml.cpp_types import Action, App, Component, StoringController, esphomelib_ns
api_ns = esphome_ns.namespace('api')
api_ns = esphomelib_ns.namespace('api')
APIServer = api_ns.class_('APIServer', Component, StoringController)
HomeAssistantServiceCallAction = api_ns.class_('HomeAssistantServiceCallAction', Action)
KeyValuePair = api_ns.class_('KeyValuePair')
@@ -74,15 +74,15 @@ def homeassistant_service_to_code(config, action_id, arg_type, template_arg):
add(act.set_service(config[CONF_SERVICE]))
if CONF_DATA in config:
datas = [KeyValuePair(k, v) for k, v in config[CONF_DATA].items()]
add(act.set_data(datas))
add(act.set_data(ArrayInitializer(*datas)))
if CONF_DATA_TEMPLATE in config:
datas = [KeyValuePair(k, v) for k, v in config[CONF_DATA_TEMPLATE].items()]
add(act.set_data_template(datas))
add(act.set_data_template(ArrayInitializer(*datas)))
if CONF_VARIABLES in config:
datas = []
for key, value in config[CONF_VARIABLES].items():
for value_ in process_lambda(value, []):
yield None
datas.append(TemplatableKeyValuePair(key, value_))
add(act.set_variables(datas))
add(act.set_variables(ArrayInitializer(*datas)))
yield act

View File

@@ -1,19 +1,21 @@
import voluptuous as vol
from esphome import automation, core
from esphome.automation import CONDITION_REGISTRY, Condition, maybe_simple_id
from esphome.components import mqtt
from esphome.components.mqtt import setup_mqtt_component
import esphome.config_validation as cv
from esphome.const import CONF_DELAYED_OFF, CONF_DELAYED_ON, CONF_DEVICE_CLASS, CONF_FILTERS, \
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_ON_STATE, \
CONF_STATE, CONF_TIMING, CONF_TRIGGER_ID
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, StructInitializer, add, get_variable, process_lambda
from esphome.cpp_types import App, Component, Nameable, NoArg, Trigger, bool_, esphome_ns, optional
from esphome.py_compat import string_types
CONF_ON_DOUBLE_CLICK, CONF_ON_MULTI_CLICK, CONF_ON_PRESS, CONF_ON_RELEASE, CONF_STATE, \
CONF_TIMING, CONF_TRIGGER_ID, CONF_ON_STATE
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_, \
optional
from esphomeyaml.py_compat import string_types
DEVICE_CLASSES = [
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
@@ -26,7 +28,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
binary_sensor_ns = esphome_ns.namespace('binary_sensor')
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)
@@ -51,15 +53,15 @@ HeartbeatFilter = binary_sensor_ns.class_('HeartbeatFilter', Filter, Component)
InvertFilter = binary_sensor_ns.class_('InvertFilter', Filter)
LambdaFilter = binary_sensor_ns.class_('LambdaFilter', Filter)
FILTER_KEYS = [CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA, CONF_HEARTBEAT]
FILTERS_SCHEMA = cv.ensure_list({
vol.Optional(CONF_INVERT): None,
vol.Optional(CONF_DELAYED_ON): cv.positive_time_period_milliseconds,
vol.Optional(CONF_DELAYED_OFF): cv.positive_time_period_milliseconds,
vol.Optional(CONF_HEARTBEAT): cv.positive_time_period_milliseconds,
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_HEARTBEAT): cv.invalid("The heartbeat filter has been removed in 1.11.0"),
}, cv.has_exactly_one_key(*FILTER_KEYS))
MULTI_CLICK_TIMING_SCHEMA = vol.Schema({
@@ -189,7 +191,7 @@ BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
vol.Optional(CONF_INVERTED): cv.invalid(
"The inverted binary_sensor property has been replaced by the "
"new 'invert' binary sensor filter. Please see "
"https://esphome.io/components/binary_sensor/index.html."
"https://esphomelib.com/esphomeyaml/components/binary_sensor/index.html."
),
})
@@ -203,6 +205,8 @@ def setup_filter(config):
yield App.register_component(DelayedOffFilter.new(config[CONF_DELAYED_OFF]))
elif CONF_DELAYED_ON in config:
yield App.register_component(DelayedOnFilter.new(config[CONF_DELAYED_ON]))
elif CONF_HEARTBEAT in config:
yield App.register_component(HeartbeatFilter.new(config[CONF_HEARTBEAT]))
elif CONF_LAMBDA in config:
for lambda_ in process_lambda(config[CONF_LAMBDA], [(bool_, 'x')],
return_type=optional.template(bool_)):
@@ -213,13 +217,14 @@ def setup_filter(config):
def setup_filters(config):
filters = []
for conf in config:
filter = None
for filter in setup_filter(conf):
yield None
filters.append(filter)
yield filters
yield ArrayInitializer(*filters)
def setup_binary_sensor_core_(binary_sensor_var, config):
def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config):
if CONF_INTERNAL in config:
add(binary_sensor_var.set_internal(CONF_INTERNAL))
if CONF_DEVICE_CLASS in config:
@@ -227,6 +232,7 @@ def setup_binary_sensor_core_(binary_sensor_var, config):
if CONF_INVERTED in config:
add(binary_sensor_var.set_inverted(config[CONF_INVERTED]))
if CONF_FILTERS in config:
filters = None
for filters in setup_filters(config[CONF_FILTERS]):
yield
add(binary_sensor_var.add_filters(filters))
@@ -261,6 +267,7 @@ def setup_binary_sensor_core_(binary_sensor_var, config):
('min_length', tim[CONF_MIN_LENGTH]),
('max_length', tim.get(CONF_MAX_LENGTH, 4294967294)),
))
timings = ArrayInitializer(*timings, multiline=False)
rhs = App.register_component(binary_sensor_var.make_multi_click_trigger(timings))
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
if CONF_INVALID_COOLDOWN in conf:
@@ -272,19 +279,22 @@ def setup_binary_sensor_core_(binary_sensor_var, config):
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
automation.build_automation(trigger, bool_, conf)
setup_mqtt_component(binary_sensor_var.Pget_mqtt(), config)
setup_mqtt_component(mqtt_var, config)
def setup_binary_sensor(binary_sensor_obj, config):
if not CORE.has_id(config[CONF_ID]):
binary_sensor_obj = Pvariable(config[CONF_ID], binary_sensor_obj, has_side_effects=True)
CORE.add_job(setup_binary_sensor_core_, binary_sensor_obj, config)
def setup_binary_sensor(binary_sensor_obj, mqtt_obj, config):
binary_sensor_var = Pvariable(config[CONF_ID], binary_sensor_obj,
has_side_effects=False)
mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj,
has_side_effects=False)
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)
add(App.register_binary_sensor(binary_sensor_var))
CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, config)
rhs = App.register_binary_sensor(binary_sensor_var)
mqtt_var = Pvariable(config[CONF_MQTT_ID], rhs, has_side_effects=True)
CORE.add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config)
def core_to_hass_config(data, config):
@@ -299,6 +309,7 @@ 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),

View File

@@ -1,10 +1,10 @@
import voluptuous as vol
from esphome.components import binary_sensor, sensor
from esphome.components.apds9960 import APDS9960, CONF_APDS9960_ID
import esphome.config_validation as cv
from esphome.const import CONF_DIRECTION, CONF_NAME
from esphome.cpp_generator import get_variable
from esphomeyaml.components import binary_sensor, sensor
from esphomeyaml.components.apds9960 import APDS9960, CONF_APDS9960_ID
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_DIRECTION, CONF_NAME
from esphomeyaml.cpp_generator import get_variable
DEPENDENCIES = ['apds9960']
APDS9960GestureDirectionBinarySensor = sensor.sensor_ns.class_(

View File

@@ -1,10 +1,10 @@
import voluptuous as vol
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA, CONF_NAME
from esphome.cpp_generator import add, process_lambda, variable
from esphome.cpp_types import std_vector
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')
@@ -26,10 +26,8 @@ def to_code(config):
rhs = CustomBinarySensorConstructor(template_)
custom = variable(config[CONF_ID], rhs)
for i, conf in enumerate(config[CONF_BINARY_SENSORS]):
rhs = custom.Pget_binary_sensor(i)
add(rhs.set_name(conf[CONF_NAME]))
binary_sensor.register_binary_sensor(rhs, conf)
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'

View File

@@ -1,15 +1,15 @@
import voluptuous as vol
from esphome.components import binary_sensor
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
import esphome.config_validation as cv
from esphome.const import CONF_MAC_ADDRESS, CONF_NAME
from esphome.cpp_generator import get_variable
from esphome.cpp_types import esphome_ns
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
from esphomeyaml.cpp_generator import get_variable
from esphomeyaml.cpp_types import esphomelib_ns
DEPENDENCIES = ['esp32_ble_tracker']
ESP32BLEPresenceDevice = esphome_ns.class_('ESP32BLEPresenceDevice', binary_sensor.BinarySensor)
ESP32BLEPresenceDevice = esphomelib_ns.class_('ESP32BLEPresenceDevice', binary_sensor.BinarySensor)
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(ESP32BLEPresenceDevice),
@@ -19,6 +19,7 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
def to_code(config):
hub = None
for hub in get_variable(config[CONF_ESP32_BLE_ID]):
yield
rhs = hub.make_presence_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))

View File

@@ -1,12 +1,12 @@
import voluptuous as vol
from esphome.components import binary_sensor
from esphome.components.esp32_touch import ESP32TouchComponent
import esphome.config_validation as cv
from esphome.const import CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32
from esphome.cpp_generator import get_variable
from esphome.cpp_types import global_ns
from esphome.pins import validate_gpio_pin
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.cpp_generator import get_variable
from esphomeyaml.cpp_types import global_ns
from esphomeyaml.pins import validate_gpio_pin
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]

View File

@@ -1,19 +1,21 @@
import voluptuous as vol
from esphome import pins
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_PIN
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import gpio_input_pin_expression, setup_component
from esphome.cpp_types import App, Component
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.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',
binary_sensor.BinarySensor,
Component)
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(GPIOBinarySensorComponent),
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeGPIOBinarySensor),
vol.Required(CONF_PIN): pins.gpio_input_pin_schema
}).extend(cv.COMPONENT_SCHEMA.schema))
@@ -23,9 +25,9 @@ def to_code(config):
for pin in gpio_input_pin_expression(config[CONF_PIN]):
yield
rhs = App.make_gpio_binary_sensor(config[CONF_NAME], pin)
gpio = Pvariable(config[CONF_ID], rhs)
binary_sensor.setup_binary_sensor(gpio, config)
setup_component(gpio, config)
gpio = variable(config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(gpio.Pgpio, gpio.Pmqtt, config)
setup_component(gpio.Pgpio, config)
BUILD_FLAGS = '-DUSE_GPIO_BINARY_SENSOR'

View File

@@ -1,10 +1,10 @@
import voluptuous as vol
from esphome.components import binary_sensor, display
from esphome.components.display.nextion import Nextion
import esphome.config_validation as cv
from esphome.const import CONF_COMPONENT_ID, CONF_NAME, CONF_PAGE_ID
from esphome.cpp_generator import get_variable
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.cpp_generator import get_variable
DEPENDENCIES = ['display']

View File

@@ -1,11 +1,11 @@
import voluptuous as vol
from esphome.components import binary_sensor
from esphome.components.pn532 import PN532Component
import esphome.config_validation as cv
from esphome.const import CONF_NAME, CONF_UID
from esphome.core import HexInt
from esphome.cpp_generator import get_variable
import esphomeyaml.config_validation as cv
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.cpp_generator import get_variable, ArrayInitializer
DEPENDENCIES = ['pn532']
@@ -41,7 +41,7 @@ def to_code(config):
for hub in get_variable(config[CONF_PN532_ID]):
yield
addr = [HexInt(int(x, 16)) for x in config[CONF_UID].split('-')]
rhs = hub.make_tag(config[CONF_NAME], addr)
rhs = hub.make_tag(config[CONF_NAME], ArrayInitializer(*addr, multiline=False))
binary_sensor.register_binary_sensor(rhs, config)

View File

@@ -1,9 +1,9 @@
import voluptuous as vol
from esphome.components import binary_sensor, rdm6300
import esphome.config_validation as cv
from esphome.const import CONF_NAME, CONF_UID
from esphome.cpp_generator import get_variable
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor, rdm6300
from esphomeyaml.const import CONF_NAME, CONF_UID
from esphomeyaml.cpp_generator import get_variable
DEPENDENCIES = ['rdm6300']

View File

@@ -1,60 +1,42 @@
import voluptuous as vol
from esphome.components import binary_sensor
from esphome.components.remote_receiver import RemoteReceiverComponent, remote_ns
from esphome.components.remote_transmitter import RC_SWITCH_RAW_SCHEMA, \
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.components.remote_receiver import RemoteReceiverComponent, remote_ns
from esphomeyaml.components.remote_transmitter import RC_SWITCH_RAW_SCHEMA, \
RC_SWITCH_TYPE_A_SCHEMA, RC_SWITCH_TYPE_B_SCHEMA, RC_SWITCH_TYPE_C_SCHEMA, \
RC_SWITCH_TYPE_D_SCHEMA, binary_code, build_rc_switch_protocol
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAND, CONF_DATA, \
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_ID, CONF_JVC, CONF_LG, CONF_NAME, CONF_NBITS, \
CONF_NEC, CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \
from esphomeyaml.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAND, CONF_DATA, \
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \
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, CONF_RC5
from esphome.cpp_generator import Pvariable, get_variable, progmem_array
from esphome.cpp_types import int32
CONF_STATE
from esphomeyaml.cpp_generator import ArrayInitializer, get_variable, Pvariable
DEPENDENCIES = ['remote_receiver']
REMOTE_KEYS = [CONF_JVC, CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_SAMSUNG, CONF_RAW,
REMOTE_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, CONF_SAMSUNG, 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_RC5]
CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D]
CONF_REMOTE_RECEIVER_ID = 'remote_receiver_id'
CONF_RECEIVER_ID = 'receiver_id'
RemoteReceiver = remote_ns.class_('RemoteReceiver', binary_sensor.BinarySensor)
JVCReceiver = remote_ns.class_('JVCReceiver', RemoteReceiver)
LGReceiver = remote_ns.class_('LGReceiver', RemoteReceiver)
NECReceiver = remote_ns.class_('NECReceiver', RemoteReceiver)
PanasonicReceiver = remote_ns.class_('PanasonicReceiver', RemoteReceiver)
RawReceiver = remote_ns.class_('RawReceiver', RemoteReceiver)
SamsungReceiver = remote_ns.class_('SamsungReceiver', RemoteReceiver)
SonyReceiver = remote_ns.class_('SonyReceiver', RemoteReceiver)
RC5Receiver = remote_ns.class_('RC5Receiver', RemoteReceiver)
RCSwitchRawReceiver = remote_ns.class_('RCSwitchRawReceiver', RemoteReceiver)
RCSwitchTypeAReceiver = remote_ns.class_('RCSwitchTypeAReceiver', RCSwitchRawReceiver)
RCSwitchTypeBReceiver = remote_ns.class_('RCSwitchTypeBReceiver', RCSwitchRawReceiver)
RCSwitchTypeCReceiver = remote_ns.class_('RCSwitchTypeCReceiver', RCSwitchRawReceiver)
RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', RCSwitchRawReceiver)
def validate_raw(value):
if isinstance(value, dict):
return vol.Schema({
cv.GenerateID(): cv.declare_variable_id(int32),
vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
})(value)
return validate_raw({
CONF_DATA: value
})
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(RemoteReceiver),
vol.Optional(CONF_JVC): vol.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t,
}),
vol.Optional(CONF_LG): vol.Schema({
vol.Required(CONF_DATA): cv.hex_uint32_t,
vol.Optional(CONF_NBITS, default=28): cv.one_of(28, 32, int=True),
@@ -74,11 +56,7 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
vol.Required(CONF_COMMAND): cv.hex_uint32_t,
}),
vol.Optional(CONF_RC5): vol.Schema({
vol.Required(CONF_ADDRESS): vol.All(cv.hex_int, vol.Range(min=0, max=0x1F)),
vol.Required(CONF_COMMAND): vol.All(cv.hex_int, vol.Range(min=0, max=0x3F)),
}),
vol.Optional(CONF_RAW): validate_raw,
vol.Optional(CONF_RAW): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
@@ -93,8 +71,6 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
def receiver_base(full_config):
name = full_config[CONF_NAME]
key, config = next((k, v) for k, v in full_config.items() if k in REMOTE_KEYS)
if key == CONF_JVC:
return JVCReceiver.new(name, config[CONF_DATA])
if key == CONF_LG:
return LGReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
if key == CONF_NEC:
@@ -105,11 +81,9 @@ def receiver_base(full_config):
return SamsungReceiver.new(name, config[CONF_DATA])
if key == CONF_SONY:
return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
if key == CONF_RC5:
return RC5Receiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
if key == CONF_RAW:
arr = progmem_array(config[CONF_ID], config[CONF_DATA])
return RawReceiver.new(name, arr, len(config[CONF_DATA]))
data = ArrayInitializer(*config, multiline=False)
return RawReceiver.new(name, data)
if key == CONF_RC_SWITCH_RAW:
return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))

View File

@@ -1,24 +1,27 @@
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
import esphomeyaml.config_validation as cv
from esphomeyaml.components import binary_sensor
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME
from esphomeyaml.cpp_generator import variable
from esphomeyaml.cpp_helpers import setup_component
from esphomeyaml.cpp_types import Application, Component, App
MakeStatusBinarySensor = Application.struct('MakeStatusBinarySensor')
StatusBinarySensor = binary_sensor.binary_sensor_ns.class_('StatusBinarySensor',
binary_sensor.BinarySensor,
Component)
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeStatusBinarySensor),
cv.GenerateID(): cv.declare_variable_id(StatusBinarySensor),
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_status_binary_sensor(config[CONF_NAME])
status = Pvariable(config[CONF_ID], rhs)
binary_sensor.setup_binary_sensor(status, config)
setup_component(status, config)
status = variable(config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(status.Pstatus, status.Pmqtt, config)
setup_component(status.Pstatus, config)
BUILD_FLAGS = '-DUSE_STATUS_BINARY_SENSOR'

View File

@@ -0,0 +1,39 @@
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.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',
binary_sensor.BinarySensor,
Component)
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateBinarySensor),
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTemplateBinarySensor),
vol.Required(CONF_LAMBDA): cv.lambda_,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_binary_sensor(config[CONF_NAME])
make = variable(config[CONF_MAKE_ID], rhs)
binary_sensor.setup_binary_sensor(make.Ptemplate_, make.Pmqtt, config)
setup_component(make.Ptemplate_, config)
template_ = None
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(bool_)):
yield
add(make.Ptemplate_.set_template(template_))
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'
def to_hass_config(data, config):
return binary_sensor.core_to_hass_config(data, config)

View File

@@ -1,19 +1,18 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY, maybe_simple_id
from esphome.components import mqtt
from esphome.components.mqtt import setup_mqtt_component
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, add, get_variable
from esphome.cpp_types import Action, Nameable, esphome_ns
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_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({
})
cover_ns = esphome_ns.namespace('cover')
cover_ns = esphomelib_ns.namespace('cover')
Cover = cover_ns.class_('Cover', Nameable)
MQTTCoverComponent = cover_ns.class_('MQTTCoverComponent', mqtt.MQTTComponent)
@@ -22,12 +21,6 @@ CoverState = cover_ns.class_('CoverState')
COVER_OPEN = cover_ns.COVER_OPEN
COVER_CLOSED = cover_ns.COVER_CLOSED
validate_cover_state = cv.one_of('OPEN', 'CLOSED', upper=True)
COVER_STATES = {
'OPEN': COVER_OPEN,
'CLOSED': COVER_CLOSED,
}
# Actions
OpenAction = cover_ns.class_('OpenAction', Action)
CloseAction = cover_ns.class_('CloseAction', Action)
@@ -41,14 +34,16 @@ COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
COVER_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(COVER_SCHEMA.schema)
def setup_cover_core_(cover_var, config):
def setup_cover_core_(cover_var, mqtt_var, config):
if CONF_INTERNAL in config:
add(cover_var.set_internal(config[CONF_INTERNAL]))
setup_mqtt_component(cover_var.Pget_mqtt(), config)
setup_mqtt_component(mqtt_var, config)
def setup_cover(cover_obj, config):
CORE.add_job(setup_cover_core_, cover_obj, config)
def setup_cover(cover_obj, mqtt_obj, config):
cover_var = Pvariable(config[CONF_ID], cover_obj, has_side_effects=False)
mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False)
setup_cover_core_(cover_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_COVER'

View File

@@ -0,0 +1,60 @@
import voluptuous as vol
import esphomeyaml.config_validation as cv
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.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)
PLATFORM_SCHEMA = cv.nameable(cover.COVER_PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeTemplateCover),
cv.GenerateID(): cv.declare_variable_id(TemplateCover),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True),
vol.Optional(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
vol.Optional(CONF_STOP_ACTION): automation.validate_automation(single=True),
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_LAMBDA, CONF_OPTIMISTIC))
def to_code(config):
rhs = App.make_template_cover(config[CONF_NAME])
make = variable(config[CONF_MAKE_ID], rhs)
cover.setup_cover(make.Ptemplate_, make.Pmqtt, config)
setup_component(make.Ptemplate_, config)
if CONF_LAMBDA in config:
for template_ in process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(cover.CoverState)):
yield
add(make.Ptemplate_.set_state_lambda(template_))
if CONF_OPEN_ACTION in config:
automation.build_automation(make.Ptemplate_.get_open_trigger(), NoArg,
config[CONF_OPEN_ACTION])
if CONF_CLOSE_ACTION in config:
automation.build_automation(make.Ptemplate_.get_close_trigger(), NoArg,
config[CONF_CLOSE_ACTION])
if CONF_STOP_ACTION in config:
automation.build_automation(make.Ptemplate_.get_stop_trigger(), NoArg,
config[CONF_STOP_ACTION])
if CONF_OPTIMISTIC in config:
add(make.Ptemplate_.set_optimistic(config[CONF_OPTIMISTIC]))
BUILD_FLAGS = '-DUSE_TEMPLATE_COVER'
def to_hass_config(data, config):
ret = cover.core_to_hass_config(data, config)
if ret is None:
return None
if CONF_OPTIMISTIC in config:
ret['optimistic'] = config[CONF_OPTIMISTIC]
return ret

View File

@@ -1,12 +1,12 @@
import voluptuous as vol
import esphome.config_validation as cv
from esphome.const import CONF_COMPONENTS, CONF_ID, CONF_LAMBDA
from esphome.cpp_generator import Pvariable, process_lambda, variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Component, ComponentPtr, esphome_ns, std_vector
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 = esphome_ns.class_('CustomComponentConstructor')
CustomComponentConstructor = esphomelib_ns.class_('CustomComponentConstructor')
MULTI_CONF = True
CONFIG_SCHEMA = vol.Schema({
@@ -25,9 +25,8 @@ def to_code(config):
rhs = CustomComponentConstructor(template_)
custom = variable(config[CONF_ID], rhs)
for i, comp_config in enumerate(config.get(CONF_COMPONENTS, [])):
comp = Pvariable(comp_config[CONF_ID], custom.get_component(i))
setup_component(comp, comp_config)
for i, comp in enumerate(config.get(CONF_COMPONENTS, [])):
setup_component(custom.get_component(i), comp)
BUILD_FLAGS = '-DUSE_CUSTOM_COMPONENT'

View File

@@ -1,12 +1,12 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_PIN, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
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.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

View File

@@ -1,7 +1,7 @@
import voluptuous as vol
from esphome.cpp_generator import add
from esphome.cpp_types import App
from esphomeyaml.cpp_generator import add
from esphomeyaml.cpp_types import App
DEPENDENCIES = ['logger']

View File

@@ -1,12 +1,12 @@
import voluptuous as vol
from esphome import config_validation as cv, pins
from esphome.automation import ACTION_REGISTRY, maybe_simple_id
from esphome.const import CONF_ID, CONF_MODE, CONF_NUMBER, CONF_PINS, CONF_RUN_CYCLES, \
from esphomeyaml import config_validation as cv, pins
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
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 esphome.cpp_generator import Pvariable, StructInitializer, add, get_variable
from esphome.cpp_helpers import gpio_input_pin_expression, setup_component
from esphome.cpp_types import Action, App, Component, esphome_ns, global_ns
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):
@@ -17,11 +17,11 @@ def validate_pin_number(value):
return value
DeepSleepComponent = esphome_ns.class_('DeepSleepComponent', Component)
EnterDeepSleepAction = esphome_ns.class_('EnterDeepSleepAction', Action)
PreventDeepSleepAction = esphome_ns.class_('PreventDeepSleepAction', Action)
DeepSleepComponent = esphomelib_ns.class_('DeepSleepComponent', Component)
EnterDeepSleepAction = esphomelib_ns.class_('EnterDeepSleepAction', Action)
PreventDeepSleepAction = esphomelib_ns.class_('PreventDeepSleepAction', Action)
WakeupPinMode = esphome_ns.enum('WakeupPinMode')
WakeupPinMode = esphomelib_ns.enum('WakeupPinMode')
WAKEUP_PIN_MODES = {
'IGNORE': WakeupPinMode.WAKEUP_PIN_MODE_IGNORE,
'KEEP_AWAKE': WakeupPinMode.WAKEUP_PIN_MODE_KEEP_AWAKE,
@@ -29,7 +29,7 @@ WAKEUP_PIN_MODES = {
}
esp_sleep_ext1_wakeup_mode_t = global_ns.enum('esp_sleep_ext1_wakeup_mode_t')
Ext1Wakeup = esphome_ns.struct('Ext1Wakeup')
Ext1Wakeup = esphomelib_ns.struct('Ext1Wakeup')
EXT1_WAKEUP_MODES = {
'ALL_LOW': esp_sleep_ext1_wakeup_mode_t.ESP_EXT1_WAKEUP_ALL_LOW,
'ANY_HIGH': esp_sleep_ext1_wakeup_mode_t.ESP_EXT1_WAKEUP_ANY_HIGH,
@@ -49,11 +49,8 @@ CONFIG_SCHEMA = vol.Schema({
vol.Required(CONF_PINS): cv.ensure_list(pins.shorthand_input_pin, validate_pin_number),
vol.Required(CONF_MODE): cv.one_of(*EXT1_WAKEUP_MODES, upper=True),
})),
vol.Optional(CONF_RUN_CYCLES): cv.positive_int,
vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds,
vol.Optional(CONF_RUN_CYCLES): cv.invalid("The run_cycles option has been removed in 1.11.0 as "
"it was essentially the same as a run_duration of 0s."
"Please use run_duration now.")
}).extend(cv.COMPONENT_SCHEMA.schema)
@@ -68,6 +65,8 @@ def to_code(config):
add(deep_sleep.set_wakeup_pin(pin))
if CONF_WAKEUP_PIN_MODE in config:
add(deep_sleep.set_wakeup_pin_mode(WAKEUP_PIN_MODES[config[CONF_WAKEUP_PIN_MODE]]))
if CONF_RUN_CYCLES in config:
add(deep_sleep.set_run_cycles(config[CONF_RUN_CYCLES]))
if CONF_RUN_DURATION in config:
add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION]))

View File

@@ -0,0 +1,58 @@
# coding=utf-8
import voluptuous as vol
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_LAMBDA, CONF_ROTATION, CONF_UPDATE_INTERVAL
from esphomeyaml.core import CORE
from esphomeyaml.cpp_generator import add
from esphomeyaml.cpp_types import esphomelib_ns
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
display_ns = esphomelib_ns.namespace('display')
DisplayBuffer = display_ns.class_('DisplayBuffer')
DisplayBufferRef = DisplayBuffer.operator('ref')
DISPLAY_ROTATIONS = {
0: display_ns.DISPLAY_ROTATION_0_DEGREES,
90: display_ns.DISPLAY_ROTATION_90_DEGREES,
180: display_ns.DISPLAY_ROTATION_180_DEGREES,
270: display_ns.DISPLAY_ROTATION_270_DEGREES,
}
def validate_rotation(value):
value = cv.string(value)
if value.endswith(u"°"):
value = value[:-1]
try:
value = int(value)
except ValueError:
raise vol.Invalid(u"Expected integer for rotation")
return cv.one_of(*DISPLAY_ROTATIONS)(value)
BASIC_DISPLAY_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
vol.Optional(CONF_LAMBDA): cv.lambda_,
})
FULL_DISPLAY_PLATFORM_SCHEMA = BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_ROTATION): validate_rotation,
})
def setup_display_core_(display_var, config):
if CONF_UPDATE_INTERVAL in config:
add(display_var.set_update_interval(config[CONF_UPDATE_INTERVAL]))
if CONF_ROTATION in config:
add(display_var.set_rotation(DISPLAY_ROTATIONS[config[CONF_ROTATION]]))
def setup_display(display_var, config):
CORE.add_job(setup_display_core_, display_var, config)
BUILD_FLAGS = '-DUSE_DISPLAY'

View File

@@ -1,13 +1,13 @@
import voluptuous as vol
from esphome import pins
from esphome.components import display
import esphome.config_validation as cv
from esphome.const import CONF_DATA_PINS, CONF_DIMENSIONS, CONF_ENABLE_PIN, CONF_ID, \
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 esphome.cpp_generator import Pvariable, add, process_lambda
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App, PollingComponent, void
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, void
LCDDisplay = display.display_ns.class_('LCDDisplay', PollingComponent)
LCDDisplayRef = LCDDisplay.operator('ref')

View File

@@ -1,13 +1,13 @@
import voluptuous as vol
from esphome.components import display, i2c
from esphome.components.display.lcd_gpio import LCDDisplay, LCDDisplayRef, \
from esphomeyaml.components import display, i2c
from esphomeyaml.components.display.lcd_gpio import LCDDisplay, LCDDisplayRef, \
validate_lcd_dimensions
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_DIMENSIONS, CONF_ID, CONF_LAMBDA
from esphome.cpp_generator import Pvariable, add, process_lambda
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, void
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_ADDRESS, CONF_DIMENSIONS, CONF_ID, CONF_LAMBDA
from esphomeyaml.cpp_generator import Pvariable, add, process_lambda
from esphomeyaml.cpp_helpers import setup_component
from esphomeyaml.cpp_types import App, void
DEPENDENCIES = ['i2c']

View File

@@ -1,14 +1,14 @@
import voluptuous as vol
from esphome import pins
from esphome.components import display, spi
from esphome.components.spi import SPIComponent
import esphome.config_validation as cv
from esphome.const import CONF_CS_PIN, CONF_ID, CONF_INTENSITY, CONF_LAMBDA, CONF_NUM_CHIPS, \
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 esphome.cpp_generator import Pvariable, add, get_variable, process_lambda
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App, PollingComponent, void
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, void
DEPENDENCIES = ['spi']

View File

@@ -1,10 +1,10 @@
from esphome.components import display, uart
from esphome.components.uart import UARTComponent
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_UART_ID
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent, void
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.cpp_generator import Pvariable, add, get_variable, process_lambda
from esphomeyaml.cpp_helpers import setup_component
from esphomeyaml.cpp_types import App, PollingComponent, void
DEPENDENCIES = ['uart']

View File

@@ -1,26 +1,26 @@
import voluptuous as vol
from esphome import pins
from esphome.components import display
from esphome.components.display import ssd1306_spi
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_LAMBDA, CONF_MODEL, \
CONF_PAGES, CONF_RESET_PIN
from esphome.cpp_generator import Pvariable, add, process_lambda
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App, void
from esphomeyaml import pins
from esphomeyaml.components import display
from esphomeyaml.components.display import ssd1306_spi
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, void
DEPENDENCIES = ['i2c']
I2CSSD1306 = display.display_ns.class_('I2CSSD1306', ssd1306_spi.SSD1306)
PLATFORM_SCHEMA = vol.All(display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(I2CSSD1306),
vol.Required(CONF_MODEL): ssd1306_spi.SSD1306_MODEL,
vol.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_EXTERNAL_VCC): cv.boolean,
vol.Optional(CONF_ADDRESS): cv.i2c_address,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):

View File

@@ -1,14 +1,14 @@
import voluptuous as vol
from esphome import pins
from esphome.components import display, spi
from esphome.components.spi import SPIComponent
import esphome.config_validation as cv
from esphome.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, CONF_ID, CONF_LAMBDA, \
CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID, CONF_PAGES
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App, PollingComponent, void
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_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, void
DEPENDENCIES = ['spi']
@@ -29,7 +29,7 @@ MODELS = {
SSD1306_MODEL = cv.one_of(*MODELS, upper=True, space="_")
PLATFORM_SCHEMA = vol.All(display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(SPISSD1306),
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
@@ -37,7 +37,7 @@ PLATFORM_SCHEMA = vol.All(display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
vol.Required(CONF_MODEL): SSD1306_MODEL,
vol.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_EXTERNAL_VCC): cv.boolean,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):

View File

@@ -1,15 +1,15 @@
import voluptuous as vol
from esphome import pins
from esphome.components import display, spi
from esphome.components.spi import SPIComponent
import esphome.config_validation as cv
from esphome.const import CONF_BUSY_PIN, CONF_CS_PIN, CONF_DC_PIN, CONF_FULL_UPDATE_EVERY, \
CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_PAGES, CONF_RESET_PIN, CONF_SPI_ID
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda
from esphome.cpp_helpers import gpio_input_pin_expression, gpio_output_pin_expression, \
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_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.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 esphome.cpp_types import App, PollingComponent, void
from esphomeyaml.cpp_types import PollingComponent, App, void
DEPENDENCIES = ['spi']
@@ -17,6 +17,7 @@ WaveshareEPaperTypeA = display.display_ns.WaveshareEPaperTypeA
WaveshareEPaper = display.display_ns.class_('WaveshareEPaper',
PollingComponent, spi.SPIDevice, display.DisplayBuffer)
WaveshareEPaperTypeAModel = display.display_ns.enum('WaveshareEPaperTypeAModel')
WaveshareEPaperTypeBModel = display.display_ns.enum('WaveshareEPaperTypeBModel')
@@ -48,8 +49,7 @@ PLATFORM_SCHEMA = vol.All(display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_BUSY_PIN): pins.gpio_input_pin_schema,
vol.Optional(CONF_FULL_UPDATE_EVERY): cv.uint32_t,
}).extend(cv.COMPONENT_SCHEMA.schema), validate_full_update_every_only_type_a,
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
}).extend(cv.COMPONENT_SCHEMA.schema), validate_full_update_every_only_type_a)
def to_code(config):

View File

@@ -1,14 +1,14 @@
import voluptuous as vol
from esphome import config_validation as cv
from esphome.const import CONF_ID, CONF_SCAN_INTERVAL, CONF_TYPE, CONF_UUID, ESP_PLATFORM_ESP32
from esphome.cpp_generator import Pvariable, RawExpression, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component, esphome_ns
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.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]
ESP32BLEBeacon = esphome_ns.class_('ESP32BLEBeacon', Component)
ESP32BLEBeacon = esphomelib_ns.class_('ESP32BLEBeacon', Component)
CONF_MAJOR = 'major'
CONF_MINOR = 'minor'
@@ -26,7 +26,7 @@ CONFIG_SCHEMA = vol.Schema({
def to_code(config):
uuid = config[CONF_UUID].hex
uuid_arr = [RawExpression('0x{}'.format(uuid[i:i + 2])) for i in range(0, len(uuid), 2)]
rhs = App.make_esp32_ble_beacon(uuid_arr)
rhs = App.make_esp32_ble_beacon(ArrayInitializer(*uuid_arr, multiline=False))
ble = Pvariable(config[CONF_ID], rhs)
if CONF_MAJOR in config:
add(ble.set_major(config[CONF_MAJOR]))

View File

@@ -0,0 +1,41 @@
import voluptuous as vol
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.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]
CONF_ESP32_BLE_ID = 'esp32_ble_id'
ESP32BLETracker = esphomelib_ns.class_('ESP32BLETracker', Component)
XiaomiSensor = esphomelib_ns.class_('XiaomiSensor', sensor.Sensor)
XiaomiDevice = esphomelib_ns.class_('XiaomiDevice')
XIAOMI_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(XiaomiSensor)
})
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(ESP32BLETracker),
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
}).extend(cv.COMPONENT_SCHEMA.schema)
def make_address_array(address):
addr = [HexInt(i) for i in address.parts]
return ArrayInitializer(*addr, multiline=False)
def to_code(config):
rhs = App.make_esp32_ble_tracker()
ble = Pvariable(config[CONF_ID], rhs)
if CONF_SCAN_INTERVAL in config:
add(ble.set_scan_interval(config[CONF_SCAN_INTERVAL]))
setup_component(ble, config)
BUILD_FLAGS = '-DUSE_ESP32_BLE_TRACKER'

View File

@@ -1,14 +1,14 @@
import voluptuous as vol
from esphome import config_validation as cv
from esphome.components import binary_sensor
from esphome.const import CONF_HIGH_VOLTAGE_REFERENCE, CONF_ID, CONF_IIR_FILTER, \
from esphomeyaml import config_validation as cv
from esphomeyaml.components import binary_sensor
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 esphome.core import TimePeriod
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component, global_ns
from esphomeyaml.core import TimePeriod
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]

View File

@@ -1,14 +1,13 @@
import voluptuous as vol
from esphome import pins
from esphome.components import wifi
import esphome.config_validation as cv
from esphome.const import CONF_DOMAIN, CONF_ID, CONF_MANUAL_IP, CONF_STATIC_IP, CONF_TYPE, \
CONF_USE_ADDRESS, ESP_PLATFORM_ESP32
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_output_pin_expression
from esphome.cpp_types import App, Component, esphome_ns, global_ns
from esphomeyaml import pins
from esphomeyaml.components import wifi
import esphomeyaml.config_validation as cv
from esphomeyaml.const import CONF_DOMAIN, CONF_HOSTNAME, CONF_ID, CONF_MANUAL_IP, CONF_TYPE, \
ESP_PLATFORM_ESP32
from esphomeyaml.cpp_generator import Pvariable, add
from esphomeyaml.cpp_helpers import gpio_output_pin_expression
from esphomeyaml.cpp_types import App, Component, esphomelib_ns, global_ns
CONFLICTS_WITH = ['wifi']
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
@@ -19,7 +18,7 @@ CONF_MDIO_PIN = 'mdio_pin'
CONF_CLK_MODE = 'clk_mode'
CONF_POWER_PIN = 'power_pin'
EthernetType = esphome_ns.enum('EthernetType')
EthernetType = esphomelib_ns.enum('EthernetType')
ETHERNET_TYPES = {
'LAN8720': EthernetType.ETHERNET_TYPE_LAN8720,
'TLK110': EthernetType.ETHERNET_TYPE_TLK110,
@@ -33,20 +32,9 @@ CLK_MODES = {
'GPIO17_OUT': eth_clock_mode_t.ETH_CLOCK_GPIO17_OUT,
}
EthernetComponent = esphome_ns.class_('EthernetComponent', Component)
EthernetComponent = esphomelib_ns.class_('EthernetComponent', Component)
def validate(config):
if CONF_USE_ADDRESS not in config:
if CONF_MANUAL_IP in config:
use_address = str(config[CONF_MANUAL_IP][CONF_STATIC_IP])
else:
use_address = CORE.name + config[CONF_DOMAIN]
config[CONF_USE_ADDRESS] = use_address
return config
CONFIG_SCHEMA = vol.All(vol.Schema({
CONFIG_SCHEMA = vol.Schema({
cv.GenerateID(): cv.declare_variable_id(EthernetComponent),
vol.Required(CONF_TYPE): cv.one_of(*ETHERNET_TYPES, upper=True),
vol.Required(CONF_MDC_PIN): pins.output_pin,
@@ -55,11 +43,9 @@ CONFIG_SCHEMA = vol.All(vol.Schema({
vol.Optional(CONF_PHY_ADDR, default=0): vol.All(cv.int_, vol.Range(min=0, max=31)),
vol.Optional(CONF_POWER_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_MANUAL_IP): wifi.STA_MANUAL_IP_SCHEMA,
vol.Optional(CONF_HOSTNAME): cv.hostname,
vol.Optional(CONF_DOMAIN, default='.local'): cv.domain_name,
vol.Optional(CONF_USE_ADDRESS): cv.string_strict,
vol.Optional('hostname'): cv.invalid("The hostname option has been removed in 1.11.0"),
}), validate)
})
def to_code(config):
@@ -71,13 +57,15 @@ def to_code(config):
add(eth.set_mdio_pin(config[CONF_MDIO_PIN]))
add(eth.set_type(ETHERNET_TYPES[config[CONF_TYPE]]))
add(eth.set_clk_mode(CLK_MODES[config[CONF_CLK_MODE]]))
add(eth.set_use_address(config[CONF_USE_ADDRESS]))
if CONF_POWER_PIN in config:
for pin in gpio_output_pin_expression(config[CONF_POWER_PIN]):
yield
add(eth.set_power_pin(pin))
if CONF_HOSTNAME in config:
add(eth.set_hostname(config[CONF_HOSTNAME]))
if CONF_MANUAL_IP in config:
add(eth.set_manual_ip(wifi.manual_ip(config[CONF_MANUAL_IP])))

View File

@@ -1,22 +1,20 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY, maybe_simple_id
from esphome.components import mqtt
from esphome.components.mqtt import setup_mqtt_component
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID, CONF_NAME, CONF_OSCILLATING, \
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_INTERNAL, CONF_MQTT_ID, CONF_NAME, CONF_OSCILLATING, \
CONF_OSCILLATION_COMMAND_TOPIC, CONF_OSCILLATION_OUTPUT, CONF_OSCILLATION_STATE_TOPIC, \
CONF_SPEED, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, add, get_variable, templatable
from esphome.cpp_types import Action, Application, Component, Nameable, bool_, esphome_ns
from esphome.py_compat import string_types
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({
})
fan_ns = esphome_ns.namespace('fan')
fan_ns = esphomelib_ns.namespace('fan')
FanState = fan_ns.class_('FanState', Nameable, Component)
MQTTFanComponent = fan_ns.class_('MQTTFanComponent', mqtt.MQTTComponent)
MakeFan = Application.struct('MakeFan')
@@ -51,25 +49,25 @@ FAN_SPEEDS = {
}
def setup_fan_core_(fan_var, config):
def setup_fan_core_(fan_var, mqtt_var, config):
if CONF_INTERNAL in config:
add(fan_var.set_internal(config[CONF_INTERNAL]))
mqtt_ = fan_var.Pget_mqtt()
if CONF_OSCILLATION_STATE_TOPIC in config:
add(mqtt_.set_custom_oscillation_state_topic(config[CONF_OSCILLATION_STATE_TOPIC]))
add(mqtt_var.set_custom_oscillation_state_topic(config[CONF_OSCILLATION_STATE_TOPIC]))
if CONF_OSCILLATION_COMMAND_TOPIC in config:
add(mqtt_.set_custom_oscillation_command_topic(config[CONF_OSCILLATION_COMMAND_TOPIC]))
add(mqtt_var.set_custom_oscillation_command_topic(config[CONF_OSCILLATION_COMMAND_TOPIC]))
if CONF_SPEED_STATE_TOPIC in config:
add(mqtt_.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
add(mqtt_var.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
if CONF_SPEED_COMMAND_TOPIC in config:
add(mqtt_.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC]))
setup_mqtt_component(mqtt_, config)
add(mqtt_var.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC]))
setup_mqtt_component(mqtt_var, config)
def setup_fan(fan_obj, config):
def setup_fan(fan_obj, mqtt_obj, config):
fan_var = Pvariable(config[CONF_ID], fan_obj, has_side_effects=False)
CORE.add_job(setup_fan_core_, fan_var, config)
mqtt_var = Pvariable(config[CONF_MQTT_ID], mqtt_obj, has_side_effects=False)
setup_fan_core_(fan_var, mqtt_var, config)
BUILD_FLAGS = '-DUSE_FAN'
@@ -126,8 +124,6 @@ def fan_turn_on_to_code(config, action_id, arg_type, template_arg):
if CONF_SPEED in config:
for template_ in templatable(config[CONF_SPEED], arg_type, FanSpeed):
yield None
if isinstance(template_, string_types):
template_ = FAN_SPEEDS[template_]
add(action.set_speed(template_))
yield action

View File

@@ -1,11 +1,11 @@
import voluptuous as vol
from esphome.components import fan, output
import esphome.config_validation as cv
from esphome.const import CONF_MAKE_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT
from esphome.cpp_generator import add, get_variable, variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App
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.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),
@@ -26,7 +26,7 @@ def to_code(config):
yield
add(fan_struct.Poutput.set_oscillation(oscillation_output))
fan.setup_fan(fan_struct.Pstate, config)
fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config)
setup_component(fan_struct.Poutput, config)

View File

@@ -1,12 +1,12 @@
import voluptuous as vol
from esphome.components import fan, mqtt, output
import esphome.config_validation as cv
from esphome.const import CONF_HIGH, CONF_LOW, CONF_MAKE_ID, CONF_MEDIUM, CONF_NAME, \
import esphomeyaml.config_validation as cv
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 esphome.cpp_generator import add, get_variable, variable
from esphome.cpp_types import App
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),
@@ -41,7 +41,7 @@ def to_code(config):
yield
add(fan_struct.Poutput.set_oscillation(oscillation_output))
fan.setup_fan(fan_struct.Pstate, config)
fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config)
def to_hass_config(data, config):

View File

@@ -1,14 +1,14 @@
# coding=utf-8
import voluptuous as vol
from esphome import core
from esphome.components import display
import esphome.config_validation as cv
from esphome.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE
from esphome.core import CORE, HexInt
from esphome.cpp_generator import Pvariable, progmem_array, safe_exp
from esphome.cpp_types import App, uint8
from esphome.py_compat import sort_by_cmp
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 CORE, HexInt
from esphomeyaml.cpp_generator import ArrayInitializer, MockObj, Pvariable, RawExpression, add
from esphomeyaml.cpp_types import App
from esphomeyaml.py_compat import sort_by_cmp
DEPENDENCIES = ['display']
MULTI_CONF = True
@@ -74,7 +74,7 @@ FONT_SCHEMA = vol.Schema({
vol.Required(CONF_FILE): validate_truetype_file,
vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,
vol.Optional(CONF_SIZE, default=20): vol.All(cv.int_, vol.Range(min=1)),
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(uint8),
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None),
})
CONFIG_SCHEMA = vol.All(validate_pillow_installed, FONT_SCHEMA)
@@ -87,7 +87,7 @@ def to_code(config):
try:
font = ImageFont.truetype(path, config[CONF_SIZE])
except Exception as e:
raise core.EsphomeError(u"Could not load truetype file {}: {}".format(path, e))
raise core.EsphomeyamlError(u"Could not load truetype file {}: {}".format(path, e))
ascent, descent = font.getmetrics()
@@ -108,12 +108,14 @@ def to_code(config):
glyph_args[glyph] = (len(data), offset_x, offset_y, width, height)
data += glyph_data
rhs = safe_exp([HexInt(x) for x in data])
prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs)
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 config[CONF_GLYPHS]:
glyphs.append(Glyph(glyph, prog_arr, *glyph_args[glyph]))
glyphs.append(Glyph(glyph, raw_data, *glyph_args[glyph]))
rhs = App.make_font(glyphs, ascent, ascent + descent)
rhs = App.make_font(ArrayInitializer(*glyphs), ascent, ascent + descent)
Pvariable(config[CONF_ID], rhs)

Some files were not shown because too many files have changed in this diff Show More