mirror of
https://github.com/esphome/esphome.git
synced 2025-08-10 20:29:24 +00:00
Compare commits
118 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f1241af91d | ||
![]() |
7ae6777fd6 | ||
![]() |
a169d37557 | ||
![]() |
be21aa786d | ||
![]() |
9a881100e6 | ||
![]() |
c2f88776c7 | ||
![]() |
846fcb8ccd | ||
![]() |
44495c919c | ||
![]() |
d4ce7699d4 | ||
![]() |
318bb8b254 | ||
![]() |
1ad65516cf | ||
![]() |
d4c7e6c634 | ||
![]() |
9b07bb6608 | ||
![]() |
f368255739 | ||
![]() |
083c2fce05 | ||
![]() |
c99d4e2815 | ||
![]() |
39457f7b8c | ||
![]() |
01aaf14078 | ||
![]() |
9a939d2d27 | ||
![]() |
7f91141df2 | ||
![]() |
06eeed9ee9 | ||
![]() |
5655b5fe10 | ||
![]() |
15331edb78 | ||
![]() |
4f375757a5 | ||
![]() |
0dec7cfbf8 | ||
![]() |
f51d301d53 | ||
![]() |
c3b3ba4923 | ||
![]() |
30e7797577 | ||
![]() |
0e5cabadc1 | ||
![]() |
58f4fa53d0 | ||
![]() |
04dc848620 | ||
![]() |
8203b8fcd3 | ||
![]() |
0ad61f4a95 | ||
![]() |
9fd4076ab8 | ||
![]() |
a9e799cb06 | ||
![]() |
3ec931ffa4 | ||
![]() |
e3094d9689 | ||
![]() |
3594779401 | ||
![]() |
94978d0063 | ||
![]() |
415e12309b | ||
![]() |
aa5f887ff3 | ||
![]() |
28561ea6a4 | ||
![]() |
3b3ff4fea9 | ||
![]() |
6b8125f5f2 | ||
![]() |
ab43390983 | ||
![]() |
611592170b | ||
![]() |
8a58ff91c3 | ||
![]() |
27b86d89b0 | ||
![]() |
36da3b85d5 | ||
![]() |
d7d3a4aa36 | ||
![]() |
4e4ffc3a24 | ||
![]() |
4dce7fa103 | ||
![]() |
467ef9902f | ||
![]() |
486174073b | ||
![]() |
e9d9de448e | ||
![]() |
08c16020c6 | ||
![]() |
0ade9baf65 | ||
![]() |
2fab7e73b9 | ||
![]() |
af4e2bf61d | ||
![]() |
6a2e9a8503 | ||
![]() |
74fefea5bb | ||
![]() |
21c22fe04a | ||
![]() |
70206df8b5 | ||
![]() |
15732ca465 | ||
![]() |
8e0f4f93d4 | ||
![]() |
361baea17f | ||
![]() |
8bbfbc4cc1 | ||
![]() |
8c5d12df51 | ||
![]() |
25c66ed8ca | ||
![]() |
7a55521807 | ||
![]() |
d04de7baeb | ||
![]() |
4aeb756388 | ||
![]() |
92b6ed4180 | ||
![]() |
9efd9f4fe8 | ||
![]() |
34fc2147a4 | ||
![]() |
629f2b128e | ||
![]() |
81bc400340 | ||
![]() |
75628b96a1 | ||
![]() |
b1f7ed4fdc | ||
![]() |
b8d7185d99 | ||
![]() |
2d20a1c0fb | ||
![]() |
820067ae5a | ||
![]() |
db8313e0d5 | ||
![]() |
27a77c685d | ||
![]() |
e34365dc7c | ||
![]() |
8d395e5338 | ||
![]() |
6f54afec00 | ||
![]() |
6a24145be6 | ||
![]() |
4a2cdbf31c | ||
![]() |
1d75ed1ff4 | ||
![]() |
76b1c6f47b | ||
![]() |
06371c9e2d | ||
![]() |
a9c130dd50 | ||
![]() |
1f82c1a483 | ||
![]() |
cb28429231 | ||
![]() |
f2cd2ec178 | ||
![]() |
37360bb797 | ||
![]() |
6c1dc0f2b3 | ||
![]() |
f7671f0c90 | ||
![]() |
639b97ccb2 | ||
![]() |
0374b3a0b3 | ||
![]() |
7ce753b76f | ||
![]() |
05a1089ed2 | ||
![]() |
71947bb6ac | ||
![]() |
ef54e33b70 | ||
![]() |
12f20fc3cf | ||
![]() |
ffdcddc18e | ||
![]() |
85d70eb5a0 | ||
![]() |
ffb793177a | ||
![]() |
d3f2fab88a | ||
![]() |
0fa52d0ce6 | ||
![]() |
cf264a2743 | ||
![]() |
433b605bef | ||
![]() |
6e60c6493a | ||
![]() |
4e63bc96d5 | ||
![]() |
ce4b339d16 | ||
![]() |
ab6d293d0d | ||
![]() |
5e5137960d |
47
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
47
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us 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!
|
||||
-->
|
||||
|
||||
**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
|
||||
|
||||
```
|
||||
|
||||
**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:**
|
22
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
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.
|
||||
-->
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
<!--
|
||||
A clear and concise description of what the problem is.
|
||||
-->
|
||||
Ex. I'm always frustrated when [...]
|
||||
|
||||
**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.
|
20
.github/ISSUE_TEMPLATE/new-integration.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/new-integration.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: New integration
|
||||
about: Suggest a new integration for esphomelib
|
||||
|
||||
---
|
||||
|
||||
<!-- READ THIS FIRST:
|
||||
- This is for new integrations (such as new sensors/modules) only, for new features within the environment please use the "feature request" template.
|
||||
- Do not delete anything from this template and fill out the form as precisely as possible.
|
||||
-->
|
||||
|
||||
**What new integration would you wish to have?**
|
||||
<!-- A name/description of the new integration/board. -->
|
||||
|
||||
**If possible, provide a link to an existing library for the integration:**
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Additional context**
|
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
## Description:
|
||||
|
||||
|
||||
**Related issue (if applicable):** fixes <link to issue>
|
||||
|
||||
**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>
|
||||
|
||||
## Example entry for YAML configuration (if applicable):
|
||||
```yaml
|
||||
|
||||
```
|
||||
|
||||
## Checklist:
|
||||
- [ ] The code change is tested and works locally.
|
||||
- [ ] Tests have been added to verify that the new code works (under `tests/` folder).
|
||||
- [ ] Check this box if you have read, understand, comply, and agree with the [Code of Conduct](https://github.com/OttoWinter/esphomeyaml/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
If user exposed functionality or configuration variables are added/changed:
|
||||
- [ ] Documentation added/updated in [esphomedocs](https://github.com/OttoWinter/esphomedocs).
|
305
.gitlab-ci.yml
305
.gitlab-ci.yml
@@ -47,131 +47,274 @@ pylint:
|
||||
script:
|
||||
- pylint esphomeyaml
|
||||
|
||||
test:
|
||||
test1:
|
||||
<<: *test
|
||||
script:
|
||||
- esphomeyaml tests/test1.yaml compile
|
||||
|
||||
test2:
|
||||
<<: *test
|
||||
script:
|
||||
- esphomeyaml tests/test2.yaml compile
|
||||
|
||||
.build-hassio: &build-hassio
|
||||
<<: *docker-builder
|
||||
stage: build
|
||||
script:
|
||||
- docker run --rm --privileged hassioaddons/qemu-user-static:latest
|
||||
- BUILD_FROM=homeassistant/${ADDON_ARCH}-base-ubuntu:latest
|
||||
- ADDON_VERSION="${CI_COMMIT_TAG#v}"
|
||||
- ADDON_VERSION="${ADDON_VERSION:-${CI_COMMIT_SHA:0:7}}"
|
||||
- ESPHOMELIB_VERSION="${ESPHOMELIB_VERSION:-dev}"
|
||||
- echo "Build from ${BUILD_FROM}"
|
||||
- echo "Add-on version ${ADDON_VERSION}"
|
||||
- echo "Esphomelib version ${ESPHOMELIB_VERSION}"
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:dev"
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
|
||||
- |
|
||||
hassio-builder.sh \
|
||||
-t . \
|
||||
-i ottowinter/esphomeyaml-hassio-${ADDON_ARCH} \
|
||||
-d "$CI_REGISTRY" \
|
||||
--${ADDON_ARCH}
|
||||
docker build \
|
||||
--build-arg "BUILD_FROM=${BUILD_FROM}" \
|
||||
--build-arg "ADDON_ARCH=${ADDON_ARCH}" \
|
||||
--build-arg "ADDON_VERSION=${ADDON_VERSION}" \
|
||||
--build-arg "ESPHOMELIB_VERSION=${ESPHOMELIB_VERSION}" \
|
||||
--tag "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:dev" \
|
||||
--tag "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
--file "docker/Dockerfile.hassio" \
|
||||
.
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:dev" \
|
||||
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
|
||||
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
|
||||
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:dev"
|
||||
retry: 2
|
||||
if [ "${DO_PUSH:-true}" = true ]; then
|
||||
echo "Pushing to CI registry"
|
||||
docker push ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}
|
||||
docker push ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:dev
|
||||
fi
|
||||
|
||||
# Generic deploy template
|
||||
.deploy: &deploy
|
||||
.deploy-release: &deploy-release
|
||||
<<: *docker-builder
|
||||
stage: deploy
|
||||
script:
|
||||
- version=${CI_COMMIT_TAG:1}
|
||||
- echo "Publishing version ${version}"
|
||||
- version="${CI_COMMIT_TAG#v}"
|
||||
- echo "Publishing release version ${version}"
|
||||
- docker pull "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
|
||||
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
|
||||
- docker pull "${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
|
||||
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- docker push "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:latest"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:latest"
|
||||
- docker push "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:latest"
|
||||
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
- docker push "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
|
||||
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/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}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
|
||||
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- docker push "ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:latest"
|
||||
|
||||
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"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}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}"
|
||||
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
|
||||
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- docker push "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
|
||||
- echo "Tag ${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
- docker push "${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:rc"
|
||||
|
||||
- echo "Tag ottowinter/esphomeyaml-hassio-${ADDON_ARCH}:${version}"
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/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 \
|
||||
"${CI_REGISTRY}/esphomeyaml-hassio-${ADDON_ARCH}:${CI_COMMIT_SHA}" \
|
||||
"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" .
|
||||
- |
|
||||
docker tag \
|
||||
"${CI_REGISTRY}/ottowinter/esphomeyaml:dev" \
|
||||
"${CI_REGISTRY}/ottowinter/esphomeyaml:${CI_COMMIT_SHA}"
|
||||
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml:${CI_COMMIT_SHA}"
|
||||
- docker push "${CI_REGISTRY}/ottowinter/esphomeyaml:dev"
|
||||
- docker build -t "${CI_REGISTRY}/esphomeyaml:dev" .
|
||||
|
||||
build:armhf:
|
||||
.build-hassio-edge: &build-hassio-edge
|
||||
<<: *build-hassio
|
||||
variables:
|
||||
ADDON_ARCH: armhf
|
||||
|
||||
#build:aarch64:
|
||||
# <<: *build
|
||||
# variables:
|
||||
# ADDON_ARCH: aarch64
|
||||
|
||||
build:i386:
|
||||
<<: *build-hassio
|
||||
variables:
|
||||
ADDON_ARCH: i386
|
||||
|
||||
build:amd64:
|
||||
<<: *build-hassio
|
||||
variables:
|
||||
ADDON_ARCH: amd64
|
||||
|
||||
# Deploy jobs
|
||||
deploy:armhf:
|
||||
<<: *deploy
|
||||
variables:
|
||||
ADDON_ARCH: armhf
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?$/
|
||||
except:
|
||||
- /^(?!master).+@/
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
- /^v\d+\.\d+\.\d+b\d+$/
|
||||
|
||||
#deploy:aarch64:
|
||||
# <<: *deploy
|
||||
.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
|
||||
ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
|
||||
|
||||
#build:hassio-aarch64-edge:
|
||||
# <<: *build-hassio-edge
|
||||
# variables:
|
||||
# ADDON_ARCH: aarch64
|
||||
# only:
|
||||
# - /^v\d+\.\d+\.\d+(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?$/
|
||||
# except:
|
||||
# - /^(?!master).+@/
|
||||
# DO_PUSH: "false"
|
||||
|
||||
deploy:i386:
|
||||
<<: *deploy
|
||||
#build:hassio-aarch64:
|
||||
# <<: *build-hassio-release
|
||||
# variables:
|
||||
# ADDON_ARCH: aarch64
|
||||
# ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
|
||||
|
||||
build:hassio-i386-edge:
|
||||
<<: *build-hassio-edge
|
||||
variables:
|
||||
ADDON_ARCH: i386
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?$/
|
||||
except:
|
||||
- /^(?!master).+@/
|
||||
DO_PUSH: "false"
|
||||
|
||||
deploy:amd64:
|
||||
<<: *deploy
|
||||
build:hassio-i386:
|
||||
<<: *build-hassio-release
|
||||
variables:
|
||||
ADDON_ARCH: i386
|
||||
ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
|
||||
|
||||
build:hassio-amd64-edge:
|
||||
<<: *build-hassio-edge
|
||||
variables:
|
||||
ADDON_ARCH: amd64
|
||||
DO_PUSH: "false"
|
||||
|
||||
build:hassio-amd64:
|
||||
<<: *build-hassio-release
|
||||
variables:
|
||||
ADDON_ARCH: amd64
|
||||
ESPHOMELIB_VERSION: "${CI_COMMIT_TAG}"
|
||||
|
||||
# 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
|
||||
before_script:
|
||||
- pip install -e .
|
||||
- pip install twine
|
||||
script:
|
||||
- python setup.py sdist
|
||||
- twine upload dist/*
|
||||
tags:
|
||||
- python2.7
|
||||
- esphomeyaml-test
|
||||
|
||||
deploy-release:pypi:
|
||||
<<: *deploy-pypi
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?$/
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
except:
|
||||
- /^(?!master).+@/
|
||||
|
||||
deploy:pypi:
|
||||
stage: deploy
|
||||
before_script:
|
||||
- pip install -e .
|
||||
- pip install twine
|
||||
script:
|
||||
- python setup.py sdist
|
||||
- twine upload dist/*
|
||||
tags:
|
||||
- python2.7
|
||||
- esphomeyaml-test
|
||||
deploy-beta:pypi:
|
||||
<<: *deploy-pypi
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?$/
|
||||
- /^v\d+\.\d+\.\d+b\d+$/
|
||||
except:
|
||||
- /^(?!master).+@/
|
||||
- /^(?!rc).+@/
|
||||
|
22
.travis.yml
22
.travis.yml
@@ -2,9 +2,19 @@ sudo: false
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
- pip install tornado esptool flake8==3.5.0 pylint==1.8.4 tzlocal pillow
|
||||
script:
|
||||
- flake8 esphomeyaml
|
||||
- pylint esphomeyaml
|
||||
jobs:
|
||||
include:
|
||||
- name: "Lint"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
- pip install flake8==3.5.0 pylint==1.9.3 tzlocal pillow
|
||||
script:
|
||||
- flake8 esphomeyaml
|
||||
- pylint esphomeyaml
|
||||
- name: "Test"
|
||||
install:
|
||||
- pip install -e .
|
||||
- pip install tzlocal pillow
|
||||
script:
|
||||
- esphomeyaml tests/test1.yaml compile
|
||||
- esphomeyaml tests/test2.yaml compile
|
||||
|
46
CODE_OF_CONDUCT.md
Normal file
46
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@otto-winter.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
18
CONTRIBUTING.md
Normal file
18
CONTRIBUTING.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Contributing to esphomeyaml
|
||||
|
||||
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 [esphomelib](https://github.com/OttoWinter/esphomelib), the C++ framework behind the project.
|
||||
|
||||
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/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.
|
||||
- Sometimes I will let pull requests linger because I'm not 100% sure about them. Please feel free to ping
|
||||
me after some time.
|
25
Dockerfile
25
Dockerfile
@@ -1,26 +1,29 @@
|
||||
FROM python:2.7
|
||||
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 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
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 requirements.txt /usr/src/app/
|
||||
RUN pip install --no-cache-dir -r requirements.txt && \
|
||||
pip install --no-cache-dir tornado esptool
|
||||
|
||||
COPY docker/platformio.ini /usr/src/app/
|
||||
RUN platformio settings set enable_telemetry No && \
|
||||
platformio run -e espressif32 -e espressif8266; exit 0
|
||||
COPY docker/platformio.ini /pio/platformio.ini
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
COPY . .
|
||||
RUN pip install --no-cache-dir -e . && \
|
||||
pip install --no-cache-dir tzlocal
|
||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
|
||||
pip install --no-cache-dir --no-binary :all: tzlocal
|
||||
|
||||
WORKDIR /config
|
||||
ENTRYPOINT ["esphomeyaml"]
|
||||
CMD ["/config", "dashboard"]
|
||||
|
@@ -1,10 +1,10 @@
|
||||
# esphomeyaml for [esphomelib](https://github.com/OttoWinter/esphomelib)
|
||||
|
||||
### Getting Started Guide: https://esphomelib.com/esphomeyaml/getting-started.html
|
||||
### Getting Started Guide: https://esphomelib.com/esphomeyaml/guides/getting_started_command_line.html
|
||||
|
||||
### Available Components: https://esphomelib.com/esphomeyaml/index.html
|
||||
|
||||
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.
|
||||
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).
|
||||
|
||||
esphomeyaml will:
|
||||
|
||||
@@ -26,7 +26,7 @@ esphomeyaml configuration.yaml run
|
||||
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:** Almost all Home Assistant features are supported out of the box. Including RGB lights and many more.
|
||||
* **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.
|
||||
|
@@ -1,21 +0,0 @@
|
||||
# Dockerfile for aarch64 version of HassIO add-on
|
||||
FROM arm64v8/ubuntu:bionic
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
python-pil \
|
||||
git \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*rm -rf /var/lib/apt/lists/* /tmp/* && \
|
||||
pip install --no-cache-dir --no-binary :all: platformio && \
|
||||
platformio settings set enable_telemetry No
|
||||
|
||||
COPY docker/platformio.ini /pio/platformio.ini
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
COPY . .
|
||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
|
||||
pip install --no-cache-dir --no-binary :all: tzlocal
|
||||
|
||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
|
@@ -1,21 +0,0 @@
|
||||
# Dockerfile for amd64 version of HassIO add-on
|
||||
FROM ubuntu:bionic
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
python-pil \
|
||||
git \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*rm -rf /var/lib/apt/lists/* /tmp/* && \
|
||||
pip install --no-cache-dir --no-binary :all: platformio && \
|
||||
platformio settings set enable_telemetry No
|
||||
|
||||
COPY docker/platformio.ini /pio/platformio.ini
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
COPY . .
|
||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
|
||||
pip install --no-cache-dir --no-binary :all: tzlocal
|
||||
|
||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
|
@@ -1,31 +0,0 @@
|
||||
# Dockerfile for armhf version of HassIO add-on
|
||||
FROM homeassistant/armhf-base:latest
|
||||
|
||||
RUN apk add --no-cache \
|
||||
python2 \
|
||||
python2-dev \
|
||||
py2-pip \
|
||||
git \
|
||||
gcc \
|
||||
openssh \
|
||||
libc6-compat \
|
||||
jpeg-dev \
|
||||
zlib-dev \
|
||||
freetype-dev \
|
||||
lcms2-dev \
|
||||
openjpeg-dev \
|
||||
tiff-dev \
|
||||
libc-dev \
|
||||
linux-headers \
|
||||
&& \
|
||||
pip install --no-cache-dir --no-binary :all: platformio && \
|
||||
platformio settings set enable_telemetry No
|
||||
|
||||
COPY docker/platformio-esp8266.ini /pio/platformio.ini
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
COPY . .
|
||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
|
||||
pip install --no-cache-dir pillow tzlocal
|
||||
|
||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
|
@@ -27,6 +27,4 @@ RUN apt-get update && apt-get install -y \
|
||||
binfmt-support \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY docker/hassio-builder.sh /usr/bin/
|
||||
|
||||
WORKDIR /data
|
||||
|
42
docker/Dockerfile.hassio
Normal file
42
docker/Dockerfile.hassio
Normal file
@@ -0,0 +1,42 @@
|
||||
# Dockerfile for HassIO add-on
|
||||
ARG BUILD_FROM=homeassistant/amd64-base-ubuntu:latest
|
||||
FROM ${BUILD_FROM}
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
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
|
||||
|
||||
COPY docker/platformio.ini /pio/platformio.ini
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
ARG ESPHOMELIB_VERSION="dev"
|
||||
RUN platformio lib -g install "https://github.com/OttoWinter/esphomelib.git#${ESPHOMELIB_VERSION}"
|
||||
|
||||
COPY . .
|
||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
|
||||
pip install --no-cache-dir --no-binary :all: tzlocal
|
||||
|
||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
|
||||
|
||||
# Build arugments
|
||||
ARG ADDON_ARCH
|
||||
ARG ADDON_VERSION
|
||||
|
||||
# Labels
|
||||
LABEL \
|
||||
io.hass.name="esphomeyaml" \
|
||||
io.hass.description="esphomeyaml HassIO add-on for intelligently managing all your ESP8266/ESP32 devices." \
|
||||
io.hass.arch="${ADDON_ARCH}" \
|
||||
io.hass.type="addon" \
|
||||
io.hass.version="${ADDON_VERSION}" \
|
||||
io.hass.url="https://esphomelib.com/esphomeyaml/index.html" \
|
||||
maintainer="Otto Winter <contact@otto-winter.com>"
|
@@ -1,21 +0,0 @@
|
||||
# Dockerfile for i386 version of HassIO add-on
|
||||
FROM i386/ubuntu:bionic
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
python-pil \
|
||||
git \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*rm -rf /var/lib/apt/lists/* /tmp/* && \
|
||||
pip install --no-cache-dir --no-binary :all: platformio && \
|
||||
platformio settings set enable_telemetry No
|
||||
|
||||
COPY docker/platformio.ini /pio/platformio.ini
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
COPY . .
|
||||
RUN pip install --no-cache-dir --no-binary :all: -e . && \
|
||||
pip install --no-cache-dir --no-binary :all: tzlocal
|
||||
|
||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
|
@@ -3,4 +3,4 @@ FROM python:2.7
|
||||
COPY requirements.txt /requirements.txt
|
||||
|
||||
RUN pip install -r /requirements.txt && \
|
||||
pip install flake8==3.5.0 pylint==1.8.4 tzlocal pillow
|
||||
pip install flake8==3.5.0 pylint==1.9.3 tzlocal pillow
|
||||
|
@@ -1,318 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Based on Home Assistant's docker builder
|
||||
######################
|
||||
# Hass.io Build-env
|
||||
######################
|
||||
set -e
|
||||
|
||||
echo -- "$@"
|
||||
|
||||
#### Variable ####
|
||||
|
||||
DOCKER_TIMEOUT=20
|
||||
DOCKER_PID=-1
|
||||
DOCKER_HUB=""
|
||||
DOCKER_CACHE="true"
|
||||
DOCKER_LOCAL="false"
|
||||
TARGET=""
|
||||
IMAGE=""
|
||||
BUILD_LIST=()
|
||||
BUILD_TASKS=()
|
||||
|
||||
#### Misc functions ####
|
||||
|
||||
function print_help() {
|
||||
cat << EOF
|
||||
Hass.io build-env for ecosystem:
|
||||
docker run --rm homeassistant/{arch}-builder:latest [options]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Display this help and exit.
|
||||
|
||||
Repository / Data
|
||||
-t, --target <PATH_TO_BUILD>
|
||||
Set local folder or path inside repository for build.
|
||||
|
||||
Version/Image handling
|
||||
-i, --image <IMAGE_NAME>
|
||||
Overwrite image name of build / support {arch}
|
||||
|
||||
Architecture
|
||||
--armhf
|
||||
Build for arm.
|
||||
--amd64
|
||||
Build for intel/amd 64bit.
|
||||
--aarch64
|
||||
Build for arm 64bit.
|
||||
--i386
|
||||
Build for intel/amd 32bit.
|
||||
--all
|
||||
Build all architecture.
|
||||
|
||||
Build handling
|
||||
--no-cache
|
||||
Disable cache for the build (from latest).
|
||||
-d, --docker-hub <DOCKER_REPOSITORY>
|
||||
Set or overwrite the docker repository.
|
||||
|
||||
Use the host docker socket if mapped into container:
|
||||
/var/run/docker.sock
|
||||
|
||||
EOF
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
#### Docker functions ####
|
||||
|
||||
function start_docker() {
|
||||
local starttime
|
||||
local endtime
|
||||
|
||||
if [ -S "/var/run/docker.sock" ]; then
|
||||
echo "[INFO] Use host docker setup with '/var/run/docker.sock'"
|
||||
DOCKER_LOCAL="true"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Starting docker."
|
||||
dockerd 2> /dev/null &
|
||||
DOCKER_PID=$!
|
||||
|
||||
echo "[INFO] Waiting for docker to initialize..."
|
||||
starttime="$(date +%s)"
|
||||
endtime="$(date +%s)"
|
||||
until docker info >/dev/null 2>&1; do
|
||||
if [ $((endtime - starttime)) -le ${DOCKER_TIMEOUT} ]; then
|
||||
sleep 1
|
||||
endtime=$(date +%s)
|
||||
else
|
||||
echo "[ERROR] Timeout while waiting for docker to come up"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "[INFO] Docker was initialized"
|
||||
}
|
||||
|
||||
|
||||
function stop_docker() {
|
||||
local starttime
|
||||
local endtime
|
||||
|
||||
if [ "$DOCKER_LOCAL" == "true" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Stopping in container docker..."
|
||||
if [ "$DOCKER_PID" -gt 0 ] && kill -0 "$DOCKER_PID" 2> /dev/null; then
|
||||
starttime="$(date +%s)"
|
||||
endtime="$(date +%s)"
|
||||
|
||||
# Now wait for it to die
|
||||
kill "$DOCKER_PID"
|
||||
while kill -0 "$DOCKER_PID" 2> /dev/null; do
|
||||
if [ $((endtime - starttime)) -le ${DOCKER_TIMEOUT} ]; then
|
||||
sleep 1
|
||||
endtime=$(date +%s)
|
||||
else
|
||||
echo "[ERROR] Timeout while waiting for container docker to die"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "[WARN] Your host might have been left with unreleased resources"
|
||||
fi
|
||||
}
|
||||
|
||||
function run_build() {
|
||||
local build_dir=$1
|
||||
local repository=$2
|
||||
local image=$3
|
||||
local version=$4
|
||||
local build_arch=$5
|
||||
local docker_cli=("${!6}")
|
||||
|
||||
local push_images=()
|
||||
|
||||
# Overwrites
|
||||
if [ ! -z "$DOCKER_HUB" ]; then repository="$DOCKER_HUB"; fi
|
||||
if [ ! -z "$IMAGE" ]; then image="$IMAGE"; fi
|
||||
|
||||
# Init Cache
|
||||
if [ "$DOCKER_CACHE" == "true" ]; then
|
||||
echo "[INFO] Init cache for $repository/$image:$version"
|
||||
if docker pull "$repository/$image:latest" > /dev/null 2>&1; then
|
||||
docker_cli+=("--cache-from" "$repository/$image:latest")
|
||||
else
|
||||
docker_cli+=("--no-cache")
|
||||
echo "[WARN] No cache image found. Cache is disabled for build"
|
||||
fi
|
||||
else
|
||||
docker_cli+=("--no-cache")
|
||||
fi
|
||||
|
||||
# Build image
|
||||
echo "[INFO] Run build for $repository/$image:$version"
|
||||
docker build --pull -t "$repository/$image:$version" \
|
||||
--label "io.hass.version=$version" \
|
||||
--label "io.hass.arch=$build_arch" \
|
||||
-f "$TARGET/docker/Dockerfile.$build_arch" \
|
||||
"${docker_cli[@]}" \
|
||||
"$build_dir"
|
||||
|
||||
echo "[INFO] Finish build for $repository/$image:$version"
|
||||
docker tag "$repository/$image:$version" "$repository/$image:dev"
|
||||
}
|
||||
|
||||
|
||||
#### HassIO functions ####
|
||||
|
||||
function build_addon() {
|
||||
local build_arch=$1
|
||||
|
||||
local docker_cli=()
|
||||
local image=""
|
||||
local repository=""
|
||||
local raw_image=""
|
||||
local name=""
|
||||
local description=""
|
||||
local url=""
|
||||
local args=""
|
||||
|
||||
# Read addon config.json
|
||||
name="$(jq --raw-output '.name // empty' "$TARGET/esphomeyaml/config.json" | sed "s/'//g")"
|
||||
description="$(jq --raw-output '.description // empty' "$TARGET/esphomeyaml/config.json" | sed "s/'//g")"
|
||||
url="$(jq --raw-output '.url // empty' "$TARGET/esphomeyaml/config.json")"
|
||||
version="$(jq --raw-output '.version' "$TARGET/esphomeyaml/config.json")"
|
||||
raw_image="$(jq --raw-output '.image // empty' "$TARGET/esphomeyaml/config.json")"
|
||||
|
||||
# Read data from image
|
||||
if [ ! -z "$raw_image" ]; then
|
||||
repository="$(echo "$raw_image" | cut -f 1 -d '/')"
|
||||
image="$(echo "$raw_image" | cut -f 2 -d '/')"
|
||||
fi
|
||||
|
||||
# Set additional labels
|
||||
docker_cli+=("--label" "io.hass.name=$name")
|
||||
docker_cli+=("--label" "io.hass.description=$description")
|
||||
docker_cli+=("--label" "io.hass.type=addon")
|
||||
|
||||
if [ ! -z "$url" ]; then
|
||||
docker_cli+=("--label" "io.hass.url=$url")
|
||||
fi
|
||||
|
||||
# Start build
|
||||
run_build "$TARGET" "$repository" "$image" "$version" \
|
||||
"$build_arch" docker_cli[@]
|
||||
}
|
||||
|
||||
#### initialized cross-build ####
|
||||
|
||||
function init_crosscompile() {
|
||||
echo "[INFO] Setup crosscompiling feature"
|
||||
(
|
||||
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
|
||||
update-binfmts --enable qemu-arm
|
||||
update-binfmts --enable qemu-aarch64
|
||||
) > /dev/null 2>&1 || echo "[WARN] Can't enable crosscompiling feature"
|
||||
}
|
||||
|
||||
|
||||
function clean_crosscompile() {
|
||||
echo "[INFO] Clean crosscompiling feature"
|
||||
if [ -f /proc/sys/fs/binfmt_misc ]; then
|
||||
umount /proc/sys/fs/binfmt_misc || true
|
||||
fi
|
||||
|
||||
(
|
||||
update-binfmts --disable qemu-arm
|
||||
update-binfmts --disable qemu-aarch64
|
||||
) > /dev/null 2>&1 || echo "[WARN] No crosscompiling feature found for cleanup"
|
||||
}
|
||||
|
||||
#### Error handling ####
|
||||
|
||||
function error_handling() {
|
||||
stop_docker
|
||||
clean_crosscompile
|
||||
|
||||
exit 1
|
||||
}
|
||||
trap 'error_handling' SIGINT SIGTERM
|
||||
|
||||
#### Parse arguments ####
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
key=$1
|
||||
case ${key} in
|
||||
-h|--help)
|
||||
print_help
|
||||
;;
|
||||
-t|--target)
|
||||
TARGET=$2
|
||||
shift
|
||||
;;
|
||||
-i|--image)
|
||||
IMAGE=$2
|
||||
shift
|
||||
;;
|
||||
--no-cache)
|
||||
DOCKER_CACHE="false"
|
||||
;;
|
||||
-d|--docker-hub)
|
||||
DOCKER_HUB=$2
|
||||
shift
|
||||
;;
|
||||
--armhf)
|
||||
BUILD_LIST+=("armhf")
|
||||
;;
|
||||
--amd64)
|
||||
BUILD_LIST+=("amd64")
|
||||
;;
|
||||
--i386)
|
||||
BUILD_LIST+=("i386")
|
||||
;;
|
||||
--aarch64)
|
||||
BUILD_LIST+=("aarch64")
|
||||
;;
|
||||
--all)
|
||||
BUILD_LIST=("armhf" "amd64" "i386" "aarch64")
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "[WARN] $0 : Argument '$1' unknown will be Ignoring"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Check if an architecture is available
|
||||
if [ "${#BUILD_LIST[@]}" -eq 0 ]; then
|
||||
echo "[ERROR] You need select an architecture for build!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#### Main ####
|
||||
|
||||
mkdir -p /data
|
||||
|
||||
# Setup docker env
|
||||
init_crosscompile
|
||||
start_docker
|
||||
|
||||
# Select arch build
|
||||
for arch in "${BUILD_LIST[@]}"; do
|
||||
(build_addon "$arch") &
|
||||
BUILD_TASKS+=($!)
|
||||
done
|
||||
|
||||
# Wait until all build jobs are done
|
||||
wait "${BUILD_TASKS[@]}"
|
||||
|
||||
# Cleanup docker env
|
||||
clean_crosscompile
|
||||
stop_docker
|
||||
|
||||
exit 0
|
@@ -1,7 +0,0 @@
|
||||
; This file allows the docker build file to install the required platformio
|
||||
; platforms
|
||||
|
||||
[env:espressif8266]
|
||||
platform = espressif8266
|
||||
board = nodemcuv2
|
||||
framework = arduino
|
33
esphomeyaml-beta/config.json
Normal file
33
esphomeyaml-beta/config.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "esphomeyaml-beta",
|
||||
"version": "1.9.2",
|
||||
"slug": "esphomeyaml-beta",
|
||||
"description": "Beta version of esphomeyaml HassIO add-on.",
|
||||
"url": "https://beta.esphomelib.com/esphomeyaml/index.html",
|
||||
"startup": "application",
|
||||
"webui": "http://[HOST]:[PORT:6052]",
|
||||
"boot": "auto",
|
||||
"ports": {
|
||||
"6052/tcp": 6052,
|
||||
"6053/tcp": 6053
|
||||
},
|
||||
"auto_uart": true,
|
||||
"map": [
|
||||
"config:rw"
|
||||
],
|
||||
"arch": [
|
||||
"amd64",
|
||||
"armhf",
|
||||
"i386"
|
||||
],
|
||||
"environment": {
|
||||
"ESPHOMEYAML_OTA_HOST_PORT": "6053"
|
||||
},
|
||||
"options": {
|
||||
"password": ""
|
||||
},
|
||||
"schema": {
|
||||
"password": "str?"
|
||||
},
|
||||
"image": "ottowinter/esphomeyaml-hassio-{arch}"
|
||||
}
|
@@ -1,59 +1,24 @@
|
||||
# Dockerfile for HassIO add-on
|
||||
ARG BUILD_FROM=ubuntu:bionic
|
||||
# Dockerfile for HassIO edge add-on
|
||||
ARG BUILD_FROM=homeassistant/amd64-base-ubuntu:latest
|
||||
FROM ${BUILD_FROM}
|
||||
|
||||
# Re-declare BUILD_FROM to fix weird docker issue
|
||||
ARG BUILD_FROM
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
python \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
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
|
||||
|
||||
# On amd64 and alike, using ubuntu as the base is better as building
|
||||
# for the ESP32 only works with glibc (and ubuntu). However, on armhf
|
||||
# the build toolchain frequently procudes segfaults under ubuntu.
|
||||
# -> Use ubuntu for most architectures, except alpine for armhf
|
||||
#
|
||||
# * python and related required because this is a python project
|
||||
# * git required for platformio library dependencies downloads
|
||||
# * libc6-compat and openssh required on alpine for weird reasons
|
||||
# * disable platformio telemetry on install
|
||||
RUN /bin/bash -c "if [[ '$BUILD_FROM' = *\"ubuntu\"* ]]; then \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
python python-pip python-setuptools python-pil git && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/*; \
|
||||
else \
|
||||
apk add --no-cache \
|
||||
python2 \
|
||||
python2-dev \
|
||||
py2-pip \
|
||||
git \
|
||||
gcc \
|
||||
openssh \
|
||||
libc6-compat \
|
||||
jpeg-dev \
|
||||
zlib-dev \
|
||||
freetype-dev \
|
||||
lcms2-dev \
|
||||
openjpeg-dev \
|
||||
tiff-dev \
|
||||
libc-dev \
|
||||
linux-headers; \
|
||||
fi" && \
|
||||
pip install --no-cache-dir platformio && \
|
||||
platformio settings set enable_telemetry No
|
||||
|
||||
|
||||
# Create fake project to make platformio install all depdencies.
|
||||
# * Ignore build errors from platformio - empty project
|
||||
# * On alpine, only install ESP8266 toolchain
|
||||
COPY platformio.ini /pio/platformio.ini
|
||||
RUN /bin/bash -c "if [[ '$BUILD_FROM' = *\"ubuntu\"* ]]; then \
|
||||
platformio run -e espressif32 -e espressif8266 -d /pio; exit 0; \
|
||||
else \
|
||||
echo \"\$(head -8 /pio/platformio.ini)\" >/pio/platformio.ini; \
|
||||
platformio run -e espressif8266 -d /pio; exit 0; \
|
||||
fi"
|
||||
RUN platformio run -d /pio; rm -rf /pio
|
||||
|
||||
# Install latest esphomeyaml from git
|
||||
RUN pip install --no-cache-dir \
|
||||
git+git://github.com/OttoWinter/esphomeyaml.git && \
|
||||
RUN pip install --no-cache-dir git+https://github.com/OttoWinter/esphomeyaml.git@dev#egg=esphomeyaml && \
|
||||
pip install --no-cache-dir pillow tzlocal
|
||||
|
||||
CMD ["esphomeyaml", "/config/esphomeyaml", "dashboard"]
|
||||
|
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"squash": false,
|
||||
"build_from": {
|
||||
"aarch64": "arm64v8/ubuntu:bionic",
|
||||
"amd64": "ubuntu:bionic",
|
||||
"armhf": "homeassistant/armhf-base:latest",
|
||||
"i386": "i386/ubuntu:bionic"
|
||||
"aarch64": "homeassistant/aarch64-base-ubuntu:latest",
|
||||
"amd64": "homeassistant/amd64-base-ubuntu:latest",
|
||||
"armhf": "homeassistant/armhf-base-ubuntu:latest",
|
||||
"i386": "homeassistant/i386-base-ubuntu:latest"
|
||||
},
|
||||
"args": {}
|
||||
}
|
||||
|
@@ -1,35 +1,28 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
from collections import OrderedDict
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
from esphomeyaml import const, core, core_config, mqtt, wizard, writer, yaml_util
|
||||
from esphomeyaml import const, core, core_config, mqtt, wizard, writer, yaml_util, platformio_api
|
||||
from esphomeyaml.config import get_component, iter_components, read_config
|
||||
from esphomeyaml.const import CONF_BAUD_RATE, CONF_BUILD_PATH, CONF_DOMAIN, CONF_ESPHOMEYAML, \
|
||||
CONF_HOSTNAME, CONF_LOGGER, CONF_MANUAL_IP, CONF_NAME, CONF_STATIC_IP, CONF_USE_CUSTOM_CODE, \
|
||||
CONF_WIFI, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, _EXPRESSIONS, add, \
|
||||
add_job, color, flush_tasks, indent, quote, statement
|
||||
from esphomeyaml.helpers import AssignmentExpression, Expression, RawStatement, \
|
||||
_EXPRESSIONS, add, add_job, color, flush_tasks, indent, statement, relative_path
|
||||
from esphomeyaml.util import safe_print, run_external_command
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PRE_INITIALIZE = ['esphomeyaml', 'logger', 'wifi', 'ota', 'mqtt', 'web_server', 'i2c']
|
||||
|
||||
|
||||
def get_name(config):
|
||||
return config[CONF_ESPHOMEYAML][CONF_NAME]
|
||||
|
||||
|
||||
def get_base_path(config):
|
||||
build_path = config[CONF_ESPHOMEYAML].get(CONF_BUILD_PATH, get_name(config))
|
||||
return os.path.join(os.path.dirname(core.CONFIG_PATH), build_path)
|
||||
|
||||
|
||||
def get_serial_ports():
|
||||
# from https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports.py
|
||||
from serial.tools.list_ports import comports
|
||||
@@ -47,11 +40,11 @@ def choose_serial_port(config):
|
||||
|
||||
if not result:
|
||||
return 'OTA'
|
||||
print(u"Found multiple serial port options, please choose one:")
|
||||
safe_print(u"Found multiple serial port options, please choose one:")
|
||||
for i, (res, desc) in enumerate(result):
|
||||
print(u" [{}] {} ({})".format(i, res, desc))
|
||||
print(u" [{}] Over The Air ({})".format(len(result), get_upload_host(config)))
|
||||
print()
|
||||
safe_print(u" [{}] {} ({})".format(i, res, desc))
|
||||
safe_print(u" [{}] Over The Air ({})".format(len(result), get_upload_host(config)))
|
||||
safe_print()
|
||||
while True:
|
||||
opt = raw_input('(number): ')
|
||||
if opt in result:
|
||||
@@ -63,45 +56,23 @@ def choose_serial_port(config):
|
||||
raise ValueError
|
||||
break
|
||||
except ValueError:
|
||||
print(color('red', u"Invalid option: '{}'".format(opt)))
|
||||
safe_print(color('red', u"Invalid option: '{}'".format(opt)))
|
||||
if opt == len(result):
|
||||
return 'OTA'
|
||||
return result[opt][0]
|
||||
|
||||
|
||||
def run_platformio(*cmd, **kwargs):
|
||||
def mock_exit(return_code):
|
||||
raise SystemExit(return_code)
|
||||
|
||||
orig_argv = sys.argv
|
||||
orig_exit = sys.exit # mock sys.exit
|
||||
full_cmd = u' '.join(quote(x) for x in cmd)
|
||||
_LOGGER.info(u"Running: %s", full_cmd)
|
||||
try:
|
||||
func = kwargs.get('main')
|
||||
if func is None:
|
||||
import platformio.__main__
|
||||
func = platformio.__main__.main
|
||||
sys.argv = list(cmd)
|
||||
sys.exit = mock_exit
|
||||
return func() or 0
|
||||
except KeyboardInterrupt:
|
||||
return 1
|
||||
except SystemExit as err:
|
||||
return err.args[0]
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.error(u"Running platformio failed: %s", err)
|
||||
_LOGGER.error(u"Please try running %s locally.", full_cmd)
|
||||
finally:
|
||||
sys.argv = orig_argv
|
||||
sys.exit = orig_exit
|
||||
|
||||
|
||||
def run_miniterm(config, port, escape=False):
|
||||
import serial
|
||||
baud_rate = config.get(CONF_LOGGER, {}).get(CONF_BAUD_RATE, 115200)
|
||||
if CONF_LOGGER not in config:
|
||||
_LOGGER.info("Logger is not enabled. Not starting UART logs.")
|
||||
return
|
||||
baud_rate = config['logger'][CONF_BAUD_RATE]
|
||||
if baud_rate == 0:
|
||||
_LOGGER.info("UART logging is disabled (baud_rate=0). Not starting UART logs.")
|
||||
_LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate)
|
||||
|
||||
backtrace_state = False
|
||||
with serial.Serial(port, baudrate=baud_rate) as ser:
|
||||
while True:
|
||||
try:
|
||||
@@ -114,10 +85,10 @@ def run_miniterm(config, port, escape=False):
|
||||
message = time + line
|
||||
if escape:
|
||||
message = message.replace('\033', '\\033')
|
||||
try:
|
||||
print(message)
|
||||
except UnicodeEncodeError:
|
||||
print(message.encode('ascii', 'backslashreplace'))
|
||||
safe_print(message)
|
||||
|
||||
backtrace_state = platformio_api.process_stacktrace(
|
||||
config, line, backtrace_state=backtrace_state)
|
||||
|
||||
|
||||
def write_cpp(config):
|
||||
@@ -148,20 +119,18 @@ def write_cpp(config):
|
||||
exp = exp.rhs
|
||||
all_code.append(unicode(statement(exp)))
|
||||
|
||||
writer.write_platformio_project(config, get_base_path(config))
|
||||
build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
|
||||
writer.write_platformio_project(config, build_path)
|
||||
|
||||
code_s = indent('\n'.join(line.rstrip() for line in all_code))
|
||||
cpp_path = os.path.join(get_base_path(config), 'src', 'main.cpp')
|
||||
cpp_path = os.path.join(build_path, 'src', 'main.cpp')
|
||||
writer.write_cpp(code_s, cpp_path)
|
||||
return 0
|
||||
|
||||
|
||||
def compile_program(args, config):
|
||||
_LOGGER.info("Compiling app...")
|
||||
command = ['platformio', 'run', '-d', get_base_path(config)]
|
||||
if args.verbose:
|
||||
command.append('-v')
|
||||
return run_platformio(*command)
|
||||
return platformio_api.run_compile(config, args.verbose)
|
||||
|
||||
|
||||
def get_upload_host(config):
|
||||
@@ -177,27 +146,23 @@ def get_upload_host(config):
|
||||
def upload_using_esptool(config, port):
|
||||
import esptool
|
||||
|
||||
name = get_name(config)
|
||||
path = os.path.join(get_base_path(config), '.pioenvs', name, 'firmware.bin')
|
||||
build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
|
||||
path = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
|
||||
cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
|
||||
'--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path]
|
||||
# pylint: disable=protected-access
|
||||
return run_platformio('esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
|
||||
'--chip', 'esp8266', '--port', port, 'write_flash', '0x0',
|
||||
path, main=esptool._main)
|
||||
return run_external_command(esptool._main, *cmd)
|
||||
|
||||
|
||||
def upload_program(config, args, port):
|
||||
_LOGGER.info("Uploading binary...")
|
||||
build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
|
||||
|
||||
# if upload is to a serial port use platformio, otherwise assume ota
|
||||
serial_port = port.startswith('/') or port.startswith('COM')
|
||||
if port != 'OTA' and serial_port:
|
||||
if core.ESP_PLATFORM == ESP_PLATFORM_ESP8266 and args.use_esptoolpy:
|
||||
return upload_using_esptool(config, port)
|
||||
command = ['platformio', 'run', '-d', get_base_path(config),
|
||||
'-t', 'upload', '--upload-port', port]
|
||||
if args.verbose:
|
||||
command.append('-v')
|
||||
return run_platformio(*command)
|
||||
return platformio_api.run_upload(config, args.verbose, port)
|
||||
|
||||
if 'ota' not in config:
|
||||
_LOGGER.error("No serial port found and OTA not enabled. Can't upload!")
|
||||
@@ -211,19 +176,23 @@ def upload_program(config, args, port):
|
||||
host = get_upload_host(config)
|
||||
|
||||
from esphomeyaml.components import ota
|
||||
from esphomeyaml import espota
|
||||
from esphomeyaml import espota2
|
||||
|
||||
bin_file = os.path.join(get_base_path(config), '.pioenvs', get_name(config), 'firmware.bin')
|
||||
bin_file = os.path.join(build_path, '.pioenvs', core.NAME, 'firmware.bin')
|
||||
if args.host_port is not None:
|
||||
host_port = args.host_port
|
||||
else:
|
||||
host_port = int(os.getenv('ESPHOMEYAML_OTA_HOST_PORT', random.randint(10000, 60000)))
|
||||
espota_args = ['espota.py', '--debug', '--progress', '-i', host,
|
||||
'-p', str(ota.get_port(config)), '-f', bin_file,
|
||||
'-a', ota.get_auth(config), '-P', str(host_port)]
|
||||
if args.verbose:
|
||||
espota_args.append('-d')
|
||||
return espota.main(espota_args)
|
||||
|
||||
verbose = args.verbose
|
||||
remote_port = ota.get_port(config)
|
||||
password = ota.get_auth(config)
|
||||
|
||||
res = espota2.run_ota(host, remote_port, password, bin_file)
|
||||
if res == 0:
|
||||
return res
|
||||
_LOGGER.warn("OTA v2 method failed. Trying with legacy OTA...")
|
||||
return espota2.run_legacy_ota(verbose, host_port, host, remote_port, password, bin_file)
|
||||
|
||||
|
||||
def show_logs(config, args, port, escape=False):
|
||||
@@ -242,7 +211,7 @@ def clean_mqtt(config, args):
|
||||
def setup_log(debug=False):
|
||||
log_level = logging.DEBUG if debug else logging.INFO
|
||||
logging.basicConfig(level=log_level)
|
||||
fmt = "%(levelname)s [%(name)s] %(message)s"
|
||||
fmt = "%(levelname)s %(message)s"
|
||||
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
|
||||
datefmt = '%H:%M:%S'
|
||||
|
||||
@@ -292,7 +261,7 @@ def strip_default_ids(config):
|
||||
def command_config(args, config):
|
||||
if not args.verbose:
|
||||
config = strip_default_ids(config)
|
||||
print(yaml_util.dump(config))
|
||||
safe_print(yaml_util.dump(config))
|
||||
return 0
|
||||
|
||||
|
||||
@@ -351,7 +320,40 @@ def command_mqtt_fingerprint(args, config):
|
||||
|
||||
|
||||
def command_version(args):
|
||||
print(u"Version: {}".format(const.__version__))
|
||||
safe_print(u"Version: {}".format(const.__version__))
|
||||
return 0
|
||||
|
||||
|
||||
def command_clean(args, config):
|
||||
build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
|
||||
try:
|
||||
writer.clean_build(build_path)
|
||||
except OSError as err:
|
||||
_LOGGER.error("Error deleting build files: %s", err)
|
||||
return 1
|
||||
_LOGGER.info("Done!")
|
||||
return 0
|
||||
|
||||
|
||||
def command_hass_config(args, config):
|
||||
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.")
|
||||
data = mqtt_component.GenerateHassConfigData(config)
|
||||
hass_config = OrderedDict()
|
||||
for domain, component, conf in iter_components(config):
|
||||
if not hasattr(component, 'to_hass_config'):
|
||||
continue
|
||||
func = getattr(component, 'to_hass_config')
|
||||
ret = func(data, conf)
|
||||
if not isinstance(ret, (list, tuple)):
|
||||
ret = [ret]
|
||||
ret = [x for x in ret if x is not None]
|
||||
domain_conf = hass_config.setdefault(domain.split('.')[0], [])
|
||||
domain_conf += ret
|
||||
|
||||
safe_print(yaml_util.dump(hass_config))
|
||||
return 0
|
||||
|
||||
|
||||
@@ -375,6 +377,8 @@ POST_CONFIG_ACTIONS = {
|
||||
'run': command_run,
|
||||
'clean-mqtt': command_clean_mqtt,
|
||||
'mqtt-fingerprint': command_mqtt_fingerprint,
|
||||
'clean': command_clean,
|
||||
'hass-config': command_hass_config,
|
||||
}
|
||||
|
||||
|
||||
@@ -445,12 +449,19 @@ def parse_args(argv):
|
||||
|
||||
subparsers.add_parser('version', help="Print the esphomeyaml version and exit.")
|
||||
|
||||
subparsers.add_parser('clean', help="Delete all temporary build files.")
|
||||
|
||||
dashboard = subparsers.add_parser('dashboard',
|
||||
help="Create a simple webserver for a dashboard.")
|
||||
help="Create a simple web server for a dashboard.")
|
||||
dashboard.add_argument("--port", help="The HTTP port to open connections on.", type=int,
|
||||
default=6052)
|
||||
dashboard.add_argument("--password", help="The optional password to require for all requests.",
|
||||
type=str, default='')
|
||||
dashboard.add_argument("--open-ui", help="Open the dashboard UI in a browser.",
|
||||
action='store_true')
|
||||
|
||||
subparsers.add_parser('hass-config', help="Dump the configuration entries that should be added"
|
||||
"to Home Assistant when not using MQTT discovery.")
|
||||
|
||||
return parser.parse_args(argv[1:])
|
||||
|
||||
@@ -477,7 +488,7 @@ def run_esphomeyaml(argv):
|
||||
except ESPHomeYAMLError as e:
|
||||
_LOGGER.error(e)
|
||||
return 1
|
||||
print(u"Unknown command {}".format(args.command))
|
||||
safe_print(u"Unknown command {}".format(args.command))
|
||||
return 1
|
||||
|
||||
|
||||
|
@@ -1,37 +1,18 @@
|
||||
import copy
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import core
|
||||
from esphomeyaml.components import cover, deep_sleep, fan, output
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ABOVE, CONF_ACTION_ID, CONF_AND, CONF_AUTOMATION_ID, \
|
||||
CONF_BELOW, CONF_BLUE, CONF_BRIGHTNESS, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, \
|
||||
CONF_EFFECT, CONF_ELSE, CONF_FLASH_LENGTH, CONF_GREEN, CONF_ID, CONF_IF, CONF_LAMBDA, \
|
||||
CONF_LEVEL, CONF_OR, CONF_OSCILLATING, CONF_PAYLOAD, CONF_QOS, CONF_RANGE, CONF_RED, \
|
||||
CONF_RETAIN, CONF_SPEED, CONF_THEN, CONF_TOPIC, CONF_TRANSITION_LENGTH, CONF_TRIGGER_ID, \
|
||||
CONF_WHITE, CONF_COLOR_TEMPERATURE
|
||||
CONF_BELOW, CONF_CONDITION, CONF_CONDITION_ID, CONF_DELAY, \
|
||||
CONF_ELSE, CONF_ID, CONF_IF, CONF_LAMBDA, \
|
||||
CONF_OR, CONF_RANGE, CONF_THEN, CONF_TRIGGER_ID
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, TemplateArguments, add, add_job, \
|
||||
bool_, esphomelib_ns, float_, get_variable, process_lambda, std_string, templatable, uint32, \
|
||||
uint8
|
||||
|
||||
CONF_MQTT_PUBLISH = 'mqtt.publish'
|
||||
CONF_LIGHT_TOGGLE = 'light.toggle'
|
||||
CONF_LIGHT_TURN_OFF = 'light.turn_off'
|
||||
CONF_LIGHT_TURN_ON = 'light.turn_on'
|
||||
CONF_SWITCH_TOGGLE = 'switch.toggle'
|
||||
CONF_SWITCH_TURN_OFF = 'switch.turn_off'
|
||||
CONF_SWITCH_TURN_ON = 'switch.turn_on'
|
||||
CONF_COVER_OPEN = 'cover.open'
|
||||
CONF_COVER_CLOSE = 'cover.close'
|
||||
CONF_COVER_STOP = 'cover.stop'
|
||||
CONF_FAN_TOGGLE = 'fan.toggle'
|
||||
CONF_FAN_TURN_OFF = 'fan.turn_off'
|
||||
CONF_FAN_TURN_ON = 'fan.turn_on'
|
||||
CONF_OUTPUT_TURN_ON = 'output.turn_on'
|
||||
CONF_OUTPUT_TURN_OFF = 'output.turn_off'
|
||||
CONF_OUTPUT_SET_LEVEL = 'output.set_level'
|
||||
CONF_DEEP_SLEEP_ENTER = 'deep_sleep.enter'
|
||||
CONF_DEEP_SLEEP_PREVENT = 'deep_sleep.prevent'
|
||||
esphomelib_ns, float_, process_lambda, templatable, uint32, get_variable, PollingComponent, \
|
||||
Action, Component, Trigger
|
||||
from esphomeyaml.util import ServiceRegistry
|
||||
|
||||
|
||||
def maybe_simple_id(*validators):
|
||||
@@ -50,116 +31,48 @@ def validate_recursive_condition(value):
|
||||
|
||||
|
||||
def validate_recursive_action(value):
|
||||
return ACTIONS_SCHEMA(value)
|
||||
value = cv.ensure_list(value)[:]
|
||||
for i, item in enumerate(value):
|
||||
item = copy.deepcopy(item)
|
||||
if not isinstance(item, dict):
|
||||
raise vol.Invalid(u"Action must consist of key-value mapping! Got {}".format(item))
|
||||
key = next((x for x in item if x != CONF_ACTION_ID), None)
|
||||
if key is None:
|
||||
raise vol.Invalid(u"Key missing from action! Got {}".format(item))
|
||||
if key not in ACTION_REGISTRY:
|
||||
raise vol.Invalid(u"Unable to find action with the name '{}', is the component loaded?"
|
||||
u"".format(key))
|
||||
item.setdefault(CONF_ACTION_ID, None)
|
||||
key2 = next((x for x in item if x != CONF_ACTION_ID and x != key), None)
|
||||
if key2 is not None:
|
||||
raise vol.Invalid(u"Cannot have two actions in one item. Key '{}' overrides '{}'! "
|
||||
u"Did you forget to indent the action?"
|
||||
u"".format(key, key2))
|
||||
validator = ACTION_REGISTRY[key][0]
|
||||
value[i] = {
|
||||
CONF_ACTION_ID: cv.declare_variable_id(Action)(item[CONF_ACTION_ID]),
|
||||
key: validator(item[key])
|
||||
}
|
||||
return value
|
||||
|
||||
|
||||
ACTION_KEYS = [CONF_DELAY, CONF_MQTT_PUBLISH, CONF_LIGHT_TOGGLE, CONF_LIGHT_TURN_OFF,
|
||||
CONF_LIGHT_TURN_ON, CONF_SWITCH_TOGGLE, CONF_SWITCH_TURN_OFF, CONF_SWITCH_TURN_ON,
|
||||
CONF_LAMBDA, CONF_COVER_OPEN, CONF_COVER_CLOSE, CONF_COVER_STOP, CONF_FAN_TOGGLE,
|
||||
CONF_FAN_TURN_OFF, CONF_FAN_TURN_ON, CONF_OUTPUT_TURN_ON, CONF_OUTPUT_TURN_OFF,
|
||||
CONF_OUTPUT_SET_LEVEL, CONF_IF, CONF_DEEP_SLEEP_ENTER, CONF_DEEP_SLEEP_PREVENT]
|
||||
|
||||
ACTIONS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
|
||||
cv.GenerateID(CONF_ACTION_ID): cv.declare_variable_id(None),
|
||||
vol.Optional(CONF_DELAY): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
vol.Optional(CONF_MQTT_PUBLISH): vol.Schema({
|
||||
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
|
||||
vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos),
|
||||
vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean),
|
||||
}),
|
||||
vol.Optional(CONF_LIGHT_TOGGLE): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
}),
|
||||
vol.Optional(CONF_LIGHT_TURN_OFF): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
}),
|
||||
vol.Optional(CONF_LIGHT_TURN_ON): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'):
|
||||
cv.templatable(cv.positive_time_period_milliseconds),
|
||||
vol.Exclusive(CONF_FLASH_LENGTH, 'transformer'):
|
||||
cv.templatable(cv.positive_time_period_milliseconds),
|
||||
vol.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.positive_float),
|
||||
vol.Optional(CONF_EFFECT): cv.templatable(cv.string),
|
||||
}),
|
||||
vol.Optional(CONF_SWITCH_TOGGLE): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_SWITCH_TURN_OFF): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_SWITCH_TURN_ON): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_COVER_OPEN): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_COVER_CLOSE): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_COVER_STOP): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_COVER_OPEN): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_COVER_CLOSE): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_COVER_STOP): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_FAN_TOGGLE): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_FAN_TURN_OFF): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_FAN_TURN_ON): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
||||
vol.Optional(CONF_SPEED): cv.templatable(fan.validate_fan_speed),
|
||||
}),
|
||||
vol.Optional(CONF_OUTPUT_TURN_OFF): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
}),
|
||||
vol.Optional(CONF_OUTPUT_TURN_ON): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None)
|
||||
}),
|
||||
vol.Optional(CONF_OUTPUT_SET_LEVEL): {
|
||||
vol.Required(CONF_ID): cv.use_variable_id(None),
|
||||
vol.Required(CONF_LEVEL): cv.percentage,
|
||||
},
|
||||
vol.Optional(CONF_DEEP_SLEEP_ENTER): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(deep_sleep.DeepSleepComponent),
|
||||
}),
|
||||
vol.Optional(CONF_DEEP_SLEEP_PREVENT): maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(deep_sleep.DeepSleepComponent),
|
||||
}),
|
||||
vol.Optional(CONF_IF): vol.All({
|
||||
vol.Required(CONF_CONDITION): validate_recursive_condition,
|
||||
vol.Optional(CONF_THEN): validate_recursive_action,
|
||||
vol.Optional(CONF_ELSE): validate_recursive_action,
|
||||
}, cv.has_at_least_one_key(CONF_THEN, CONF_ELSE)),
|
||||
vol.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
}, cv.has_exactly_one_key(*ACTION_KEYS))])
|
||||
ACTION_REGISTRY = ServiceRegistry()
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
DelayAction = esphomelib_ns.DelayAction
|
||||
LambdaAction = esphomelib_ns.LambdaAction
|
||||
IfAction = esphomelib_ns.IfAction
|
||||
Automation = esphomelib_ns.Automation
|
||||
DelayAction = esphomelib_ns.class_('DelayAction', Action, Component)
|
||||
LambdaAction = esphomelib_ns.class_('LambdaAction', Action)
|
||||
IfAction = esphomelib_ns.class_('IfAction', Action)
|
||||
UpdateComponentAction = esphomelib_ns.class_('UpdateComponentAction', Action)
|
||||
Automation = esphomelib_ns.class_('Automation')
|
||||
|
||||
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)
|
||||
|
||||
CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [cv.templatable({
|
||||
cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(None),
|
||||
cv.GenerateID(CONF_CONDITION_ID): cv.declare_variable_id(Condition),
|
||||
vol.Optional(CONF_AND): validate_recursive_condition,
|
||||
vol.Optional(CONF_OR): validate_recursive_condition,
|
||||
vol.Optional(CONF_RANGE): vol.All(vol.Schema({
|
||||
@@ -169,33 +82,48 @@ CONDITIONS_SCHEMA = vol.All(cv.ensure_list, [cv.templatable({
|
||||
vol.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
})])
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
AndCondition = esphomelib_ns.AndCondition
|
||||
OrCondition = esphomelib_ns.OrCondition
|
||||
RangeCondition = esphomelib_ns.RangeCondition
|
||||
LambdaCondition = esphomelib_ns.LambdaCondition
|
||||
|
||||
|
||||
def validate_automation(extra_schema=None):
|
||||
def validate_automation(extra_schema=None, extra_validators=None, single=False):
|
||||
schema = AUTOMATION_SCHEMA.extend(extra_schema or {})
|
||||
|
||||
def validator(value):
|
||||
def validator_(value):
|
||||
if isinstance(value, list):
|
||||
return schema({CONF_THEN: value})
|
||||
try:
|
||||
# First try as a sequence of actions
|
||||
return [schema({CONF_THEN: value})]
|
||||
except vol.Invalid as err:
|
||||
# Next try as a sequence of automations
|
||||
try:
|
||||
return vol.Schema([schema])(value)
|
||||
except vol.Invalid as err2:
|
||||
if 'Unable to find action' in str(err):
|
||||
raise err2
|
||||
raise vol.MultipleInvalid([err, err2])
|
||||
elif isinstance(value, dict):
|
||||
if CONF_THEN in value:
|
||||
return schema(value)
|
||||
return schema({CONF_THEN: value})
|
||||
return schema(value)
|
||||
return [schema(value)]
|
||||
return [schema({CONF_THEN: value})]
|
||||
# This should only happen with invalid configs, but let's have a nice error message.
|
||||
return [schema(value)]
|
||||
|
||||
def validator(value):
|
||||
value = validator_(value)
|
||||
if extra_validators is not None:
|
||||
value = vol.Schema([extra_validators])(value)
|
||||
if single:
|
||||
if len(value) != 1:
|
||||
raise vol.Invalid("Cannot have more than 1 automation for templates")
|
||||
return value[0]
|
||||
return value
|
||||
|
||||
return validator
|
||||
|
||||
|
||||
AUTOMATION_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(None),
|
||||
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(None),
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(Trigger),
|
||||
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(Automation),
|
||||
vol.Optional(CONF_IF): CONDITIONS_SCHEMA,
|
||||
vol.Required(CONF_THEN): ACTIONS_SCHEMA,
|
||||
vol.Required(CONF_THEN): validate_recursive_action,
|
||||
})
|
||||
|
||||
|
||||
@@ -245,227 +173,84 @@ def build_conditions(config, arg_type):
|
||||
yield ArrayInitializer(*conditions)
|
||||
|
||||
|
||||
def build_action(full_config, arg_type):
|
||||
from esphomeyaml.components import light, mqtt, switch
|
||||
DELAY_ACTION_SCHEMA = cv.templatable(cv.positive_time_period_milliseconds)
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_DELAY, DELAY_ACTION_SCHEMA)
|
||||
def delay_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
# Keep pylint from freaking out
|
||||
var = None
|
||||
action_id = full_config[CONF_ACTION_ID]
|
||||
key, config = next((k, v) for k, v in full_config.items() if k in ACTION_KEYS)
|
||||
if key == CONF_DELAY:
|
||||
rhs = App.register_component(DelayAction.new(template_arg))
|
||||
type = DelayAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config, arg_type, uint32):
|
||||
yield
|
||||
add(action.set_delay(template_))
|
||||
yield action
|
||||
elif key == CONF_LAMBDA:
|
||||
for lambda_ in process_lambda(config, [(arg_type, 'x')]):
|
||||
yield None
|
||||
rhs = LambdaAction.new(template_arg, lambda_)
|
||||
type = LambdaAction.template(template_arg)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_MQTT_PUBLISH:
|
||||
rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg)
|
||||
type = mqtt.MQTTPublishAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
|
||||
yield None
|
||||
add(action.set_topic(template_))
|
||||
rhs = App.register_component(DelayAction.new(template_arg))
|
||||
type = DelayAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config, arg_type, uint32):
|
||||
yield
|
||||
add(action.set_delay(template_))
|
||||
yield action
|
||||
|
||||
for template_ in templatable(config[CONF_PAYLOAD], arg_type, std_string):
|
||||
|
||||
IF_ACTION_SCHEMA = vol.All({
|
||||
vol.Required(CONF_CONDITION): validate_recursive_condition,
|
||||
vol.Optional(CONF_THEN): validate_recursive_action,
|
||||
vol.Optional(CONF_ELSE): validate_recursive_action,
|
||||
}, cv.has_at_least_one_key(CONF_THEN, CONF_ELSE))
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_IF, IF_ACTION_SCHEMA)
|
||||
def if_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for conditions in build_conditions(config[CONF_CONDITION], arg_type):
|
||||
yield None
|
||||
rhs = IfAction.new(template_arg, conditions)
|
||||
type = IfAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_THEN in config:
|
||||
for actions in build_actions(config[CONF_THEN], arg_type):
|
||||
yield None
|
||||
add(action.set_payload(template_))
|
||||
if CONF_QOS in config:
|
||||
for template_ in templatable(config[CONF_QOS], arg_type, uint8):
|
||||
yield
|
||||
add(action.set_qos(template_))
|
||||
if CONF_RETAIN in config:
|
||||
for template_ in templatable(config[CONF_RETAIN], arg_type, bool_):
|
||||
yield None
|
||||
add(action.set_retain(template_))
|
||||
yield action
|
||||
elif key == CONF_LIGHT_TOGGLE:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
add(action.add_then(actions))
|
||||
if CONF_ELSE in config:
|
||||
for actions in build_actions(config[CONF_ELSE], arg_type):
|
||||
yield None
|
||||
rhs = var.make_toggle_action(template_arg)
|
||||
type = light.ToggleAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_transition_length(template_))
|
||||
yield action
|
||||
elif key == CONF_LIGHT_TURN_OFF:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = light.TurnOffAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_transition_length(template_))
|
||||
yield action
|
||||
elif key == CONF_LIGHT_TURN_ON:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = light.TurnOnAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_transition_length(template_))
|
||||
if CONF_FLASH_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_FLASH_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_flash_length(template_))
|
||||
if CONF_BRIGHTNESS in config:
|
||||
for template_ in templatable(config[CONF_BRIGHTNESS], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_brightness(template_))
|
||||
if CONF_RED in config:
|
||||
for template_ in templatable(config[CONF_RED], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_red(template_))
|
||||
if CONF_GREEN in config:
|
||||
for template_ in templatable(config[CONF_GREEN], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_green(template_))
|
||||
if CONF_BLUE in config:
|
||||
for template_ in templatable(config[CONF_BLUE], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_blue(template_))
|
||||
if CONF_WHITE in config:
|
||||
for template_ in templatable(config[CONF_WHITE], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_white(template_))
|
||||
if CONF_COLOR_TEMPERATURE in config:
|
||||
for template_ in templatable(config[CONF_COLOR_TEMPERATURE], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_color_temperature(template_))
|
||||
if CONF_EFFECT in config:
|
||||
for template_ in templatable(config[CONF_EFFECT], arg_type, std_string):
|
||||
yield None
|
||||
add(action.set_effect(template_))
|
||||
yield action
|
||||
elif key == CONF_SWITCH_TOGGLE:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_toggle_action(template_arg)
|
||||
type = switch.ToggleAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_SWITCH_TURN_OFF:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = switch.TurnOffAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_SWITCH_TURN_ON:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = switch.TurnOnAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_COVER_OPEN:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_open_action(template_arg)
|
||||
type = cover.OpenAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_COVER_CLOSE:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_close_action(template_arg)
|
||||
type = cover.CloseAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_COVER_STOP:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_stop_action(template_arg)
|
||||
type = cover.StopAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_FAN_TOGGLE:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_toggle_action(template_arg)
|
||||
type = fan.ToggleAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_FAN_TURN_OFF:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = fan.TurnOffAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_FAN_TURN_ON:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = fan.TurnOnAction.template(arg_type)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_OSCILLATING in config:
|
||||
for template_ in templatable(config[CONF_OSCILLATING], arg_type, bool_):
|
||||
yield None
|
||||
add(action.set_oscillating(template_))
|
||||
if CONF_SPEED in config:
|
||||
for template_ in templatable(config[CONF_SPEED], arg_type, fan.FanSpeed):
|
||||
yield None
|
||||
add(action.set_speed(template_))
|
||||
yield action
|
||||
elif key == CONF_OUTPUT_TURN_OFF:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = output.TurnOffAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_OUTPUT_TURN_ON:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = output.TurnOnAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_OUTPUT_SET_LEVEL:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_set_level_action(template_arg)
|
||||
type = output.SetLevelAction.template(arg_type)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config[CONF_LEVEL], arg_type, bool_):
|
||||
yield None
|
||||
add(action.set_level(template_))
|
||||
yield action
|
||||
elif key == CONF_IF:
|
||||
for conditions in build_conditions(config[CONF_CONDITION], arg_type):
|
||||
yield None
|
||||
rhs = IfAction.new(template_arg, conditions)
|
||||
type = IfAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_THEN in config:
|
||||
for actions in build_actions(config[CONF_THEN], arg_type):
|
||||
yield None
|
||||
add(action.add_then(actions))
|
||||
if CONF_ELSE in config:
|
||||
for actions in build_actions(config[CONF_ELSE], arg_type):
|
||||
yield None
|
||||
add(action.add_else(actions))
|
||||
yield action
|
||||
elif key == CONF_DEEP_SLEEP_ENTER:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_enter_deep_sleep_action(template_arg)
|
||||
type = deep_sleep.EnterDeepSleepAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
elif key == CONF_DEEP_SLEEP_PREVENT:
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_prevent_deep_sleep_action(template_arg)
|
||||
type = deep_sleep.PreventDeepSleepAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
else:
|
||||
raise ESPHomeYAMLError(u"Unsupported action {}".format(config))
|
||||
add(action.add_else(actions))
|
||||
yield action
|
||||
|
||||
|
||||
LAMBDA_ACTION_SCHEMA = cv.lambda_
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_LAMBDA, LAMBDA_ACTION_SCHEMA)
|
||||
def lambda_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for lambda_ in process_lambda(config, [(arg_type, 'x')]):
|
||||
yield None
|
||||
rhs = LambdaAction.new(template_arg, lambda_)
|
||||
type = LambdaAction.template(template_arg)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_COMPONENT_UPDATE = 'component.update'
|
||||
COMPONENT_UPDATE_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(PollingComponent),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_COMPONENT_UPDATE, COMPONENT_UPDATE_ACTION_SCHEMA)
|
||||
def component_update_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = UpdateComponentAction.new(var)
|
||||
type = UpdateComponentAction.template(template_arg)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
def build_action(full_config, arg_type):
|
||||
action_id = full_config[CONF_ACTION_ID]
|
||||
key, config = next((k, v) for k, v in full_config.items() if k in ACTION_REGISTRY)
|
||||
|
||||
builder = ACTION_REGISTRY[key][1]
|
||||
for result in builder(config, action_id, arg_type):
|
||||
yield None
|
||||
yield result
|
||||
|
||||
|
||||
def build_actions(config, arg_type):
|
||||
|
@@ -1,22 +1,18 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.components import sensor, i2c
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_RATE
|
||||
from esphomeyaml.helpers import App, Pvariable
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, setup_component, Component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
ADS1115Component = sensor.sensor_ns.ADS1115Component
|
||||
|
||||
RATE_REMOVE_MESSAGE = """The rate option has been removed in 1.5.0 and is no longer required."""
|
||||
ADS1115Component = sensor.sensor_ns.class_('ADS1115Component', Component, i2c.I2CDevice)
|
||||
|
||||
ADS1115_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(ADS1115Component),
|
||||
vol.Required(CONF_ADDRESS): cv.i2c_address,
|
||||
|
||||
vol.Optional(CONF_RATE): cv.invalid(RATE_REMOVE_MESSAGE)
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
|
||||
|
||||
@@ -24,7 +20,8 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [ADS1115_SCHEMA])
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
rhs = App.make_ads1115_component(conf[CONF_ADDRESS])
|
||||
Pvariable(conf[CONF_ID], rhs)
|
||||
var = Pvariable(conf[CONF_ID], rhs)
|
||||
setup_component(var, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
|
||||
|
@@ -1,13 +1,16 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import automation, core
|
||||
from esphomeyaml.components import mqtt
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import automation
|
||||
from esphomeyaml.const import CONF_DEVICE_CLASS, CONF_ID, CONF_INTERNAL, CONF_INVERTED, \
|
||||
CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, CONF_ON_DOUBLE_CLICK, \
|
||||
CONF_ON_PRESS, CONF_ON_RELEASE, CONF_TRIGGER_ID, CONF_FILTERS, CONF_INVERT, CONF_DELAYED_ON, \
|
||||
CONF_DELAYED_OFF, CONF_LAMBDA, CONF_HEARTBEAT
|
||||
from esphomeyaml.helpers import App, NoArg, Pvariable, add, add_job, esphomelib_ns, \
|
||||
setup_mqtt_component, bool_, process_lambda, ArrayInitializer
|
||||
from esphomeyaml.const import CONF_DELAYED_OFF, CONF_DELAYED_ON, CONF_DEVICE_CLASS, CONF_FILTERS, \
|
||||
CONF_HEARTBEAT, CONF_ID, CONF_INTERNAL, CONF_INVALID_COOLDOWN, CONF_INVERT, CONF_INVERTED, \
|
||||
CONF_LAMBDA, CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_MQTT_ID, CONF_ON_CLICK, \
|
||||
CONF_ON_DOUBLE_CLICK, CONF_ON_MULTI_CLICK, CONF_ON_PRESS, CONF_ON_RELEASE, CONF_STATE, \
|
||||
CONF_TIMING, CONF_TRIGGER_ID
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, NoArg, Pvariable, StructInitializer, add, \
|
||||
add_job, bool_, esphomelib_ns, process_lambda, setup_mqtt_component, Nameable, Trigger, \
|
||||
Component
|
||||
|
||||
DEVICE_CLASSES = [
|
||||
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
|
||||
@@ -21,19 +24,27 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
})
|
||||
|
||||
binary_sensor_ns = esphomelib_ns.namespace('binary_sensor')
|
||||
PressTrigger = binary_sensor_ns.PressTrigger
|
||||
ReleaseTrigger = binary_sensor_ns.ReleaseTrigger
|
||||
ClickTrigger = binary_sensor_ns.ClickTrigger
|
||||
DoubleClickTrigger = binary_sensor_ns.DoubleClickTrigger
|
||||
BinarySensor = binary_sensor_ns.BinarySensor
|
||||
InvertFilter = binary_sensor_ns.InvertFilter
|
||||
LambdaFilter = binary_sensor_ns.LambdaFilter
|
||||
DelayedOnFilter = binary_sensor_ns.DelayedOnFilter
|
||||
DelayedOffFilter = binary_sensor_ns.DelayedOffFilter
|
||||
HeartbeatFilter = binary_sensor_ns.HeartbeatFilter
|
||||
MQTTBinarySensorComponent = binary_sensor_ns.MQTTBinarySensorComponent
|
||||
BinarySensor = binary_sensor_ns.class_('BinarySensor', Nameable)
|
||||
MQTTBinarySensorComponent = binary_sensor_ns.class_('MQTTBinarySensorComponent', mqtt.MQTTComponent)
|
||||
|
||||
FILTER_KEYS = [CONF_INVERT, CONF_DELAYED_ON, CONF_DELAYED_OFF, CONF_LAMBDA]
|
||||
# Triggers
|
||||
PressTrigger = binary_sensor_ns.class_('PressTrigger', Trigger.template(NoArg))
|
||||
ReleaseTrigger = binary_sensor_ns.class_('ReleaseTrigger', Trigger.template(NoArg))
|
||||
ClickTrigger = binary_sensor_ns.class_('ClickTrigger', Trigger.template(NoArg))
|
||||
DoubleClickTrigger = binary_sensor_ns.class_('DoubleClickTrigger', Trigger.template(NoArg))
|
||||
MultiClickTrigger = binary_sensor_ns.class_('MultiClickTrigger', Trigger.template(NoArg), Component)
|
||||
MultiClickTriggerEvent = binary_sensor_ns.struct('MultiClickTriggerEvent')
|
||||
|
||||
# Filters
|
||||
Filter = binary_sensor_ns.class_('Filter')
|
||||
DelayedOnFilter = binary_sensor_ns.class_('DelayedOnFilter', Filter, Component)
|
||||
DelayedOffFilter = binary_sensor_ns.class_('DelayedOffFilter', Filter, Component)
|
||||
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 = vol.All(cv.ensure_list, [vol.All({
|
||||
vol.Optional(CONF_INVERT): None,
|
||||
@@ -43,29 +54,126 @@ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
|
||||
vol.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
}, cv.has_exactly_one_key(*FILTER_KEYS))])
|
||||
|
||||
MULTI_CLICK_TIMING_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_STATE): cv.boolean,
|
||||
vol.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
|
||||
|
||||
def parse_multi_click_timing_str(value):
|
||||
if not isinstance(value, basestring):
|
||||
return value
|
||||
|
||||
parts = value.lower().split(' ')
|
||||
if len(parts) != 5:
|
||||
raise vol.Invalid("Multi click timing grammar consists of exactly 5 words, not {}"
|
||||
"".format(len(parts)))
|
||||
try:
|
||||
state = cv.boolean(parts[0])
|
||||
except vol.Invalid:
|
||||
raise vol.Invalid(u"First word must either be ON or OFF, not {}".format(parts[0]))
|
||||
|
||||
if parts[1] != 'for':
|
||||
raise vol.Invalid(u"Second word must be 'for', got {}".format(parts[1]))
|
||||
|
||||
if parts[2] == 'at':
|
||||
if parts[3] == 'least':
|
||||
key = CONF_MIN_LENGTH
|
||||
elif parts[3] == 'most':
|
||||
key = CONF_MAX_LENGTH
|
||||
else:
|
||||
raise vol.Invalid(u"Third word after at must either be 'least' or 'most', got {}"
|
||||
u"".format(parts[3]))
|
||||
try:
|
||||
length = cv.positive_time_period_milliseconds(parts[4])
|
||||
except vol.Invalid as err:
|
||||
raise vol.Invalid(u"Multi Click Grammar Parsing length failed: {}".format(err))
|
||||
return {
|
||||
CONF_STATE: state,
|
||||
key: str(length)
|
||||
}
|
||||
|
||||
if parts[3] != 'to':
|
||||
raise vol.Invalid("Multi click grammar: 4th word must be 'to'")
|
||||
|
||||
try:
|
||||
min_length = cv.positive_time_period_milliseconds(parts[2])
|
||||
except vol.Invalid as err:
|
||||
raise vol.Invalid(u"Multi Click Grammar Parsing minimum length failed: {}".format(err))
|
||||
|
||||
try:
|
||||
max_length = cv.positive_time_period_milliseconds(parts[4])
|
||||
except vol.Invalid as err:
|
||||
raise vol.Invalid(u"Multi Click Grammar Parsing minimum length failed: {}".format(err))
|
||||
|
||||
return {
|
||||
CONF_STATE: state,
|
||||
CONF_MIN_LENGTH: str(min_length),
|
||||
CONF_MAX_LENGTH: str(max_length)
|
||||
}
|
||||
|
||||
|
||||
def validate_multi_click_timing(value):
|
||||
if not isinstance(value, list):
|
||||
raise vol.Invalid("Timing option must be a *list* of times!")
|
||||
timings = []
|
||||
state = None
|
||||
for i, v_ in enumerate(value):
|
||||
v_ = MULTI_CLICK_TIMING_SCHEMA(v_)
|
||||
min_length = v_.get(CONF_MIN_LENGTH)
|
||||
max_length = v_.get(CONF_MAX_LENGTH)
|
||||
if min_length is None and max_length is None:
|
||||
raise vol.Invalid("At least one of min_length and max_length is required!")
|
||||
if min_length is None and max_length is not None:
|
||||
min_length = core.TimePeriodMilliseconds(milliseconds=0)
|
||||
|
||||
new_state = v_.get(CONF_STATE, not state)
|
||||
if new_state == state:
|
||||
raise vol.Invalid("Timings must have alternating state. Indices {} and {} have "
|
||||
"the same state {}".format(i, i + 1, state))
|
||||
if max_length is not None and max_length < min_length:
|
||||
raise vol.Invalid("Max length ({}) must be larger than min length ({})."
|
||||
"".format(max_length, min_length))
|
||||
|
||||
state = new_state
|
||||
tim = {
|
||||
CONF_STATE: new_state,
|
||||
CONF_MIN_LENGTH: min_length,
|
||||
}
|
||||
if max_length is not None:
|
||||
tim[CONF_MAX_LENGTH] = max_length
|
||||
timings.append(tim)
|
||||
return timings
|
||||
|
||||
|
||||
BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTBinarySensorComponent),
|
||||
cv.GenerateID(): cv.declare_variable_id(BinarySensor),
|
||||
|
||||
vol.Optional(CONF_DEVICE_CLASS): vol.All(vol.Lower, cv.one_of(*DEVICE_CLASSES)),
|
||||
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA,
|
||||
vol.Optional(CONF_ON_PRESS): vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
vol.Optional(CONF_ON_PRESS): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PressTrigger),
|
||||
})]),
|
||||
vol.Optional(CONF_ON_RELEASE): vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
}),
|
||||
vol.Optional(CONF_ON_RELEASE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ReleaseTrigger),
|
||||
})]),
|
||||
vol.Optional(CONF_ON_CLICK): vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
}),
|
||||
vol.Optional(CONF_ON_CLICK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ClickTrigger),
|
||||
vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
|
||||
})]),
|
||||
vol.Optional(CONF_ON_DOUBLE_CLICK):
|
||||
vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(DoubleClickTrigger),
|
||||
vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
|
||||
})]),
|
||||
}),
|
||||
vol.Optional(CONF_ON_DOUBLE_CLICK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(DoubleClickTrigger),
|
||||
vol.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
|
||||
}),
|
||||
vol.Optional(CONF_ON_MULTI_CLICK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MultiClickTrigger),
|
||||
vol.Required(CONF_TIMING): vol.All([parse_multi_click_timing_str],
|
||||
validate_multi_click_timing),
|
||||
vol.Optional(CONF_INVALID_COOLDOWN): cv.positive_time_period_milliseconds,
|
||||
}),
|
||||
|
||||
vol.Optional(CONF_INVERTED): cv.invalid(
|
||||
"The inverted binary_sensor property has been replaced by the "
|
||||
@@ -137,6 +245,22 @@ def setup_binary_sensor_core_(binary_sensor_var, mqtt_var, config):
|
||||
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
|
||||
automation.build_automation(trigger, NoArg, conf)
|
||||
|
||||
for conf in config.get(CONF_ON_MULTI_CLICK, []):
|
||||
timings = []
|
||||
for tim in conf[CONF_TIMING]:
|
||||
timings.append(StructInitializer(
|
||||
MultiClickTriggerEvent,
|
||||
('state', tim[CONF_STATE]),
|
||||
('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:
|
||||
add(trigger.set_invalid_cooldown(conf[CONF_INVALID_COOLDOWN]))
|
||||
automation.build_automation(trigger, NoArg, conf)
|
||||
|
||||
setup_mqtt_component(mqtt_var, config)
|
||||
|
||||
|
||||
@@ -155,4 +279,14 @@ def register_binary_sensor(var, config):
|
||||
add_job(setup_binary_sensor_core_, binary_sensor_var, mqtt_var, config)
|
||||
|
||||
|
||||
def core_to_hass_config(data, config):
|
||||
ret = mqtt.build_hass_config(data, 'binary_sensor', config,
|
||||
include_state=True, include_command=False)
|
||||
if ret is None:
|
||||
return None
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
ret['device_class'] = config[CONF_DEVICE_CLASS]
|
||||
return ret
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_BINARY_SENSOR'
|
||||
|
@@ -1,15 +1,17 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
|
||||
make_address_array
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
|
||||
from esphomeyaml.helpers import get_variable
|
||||
from esphomeyaml.helpers import esphomelib_ns, get_variable
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
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),
|
||||
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker)
|
||||
}))
|
||||
@@ -21,3 +23,7 @@ def to_code(config):
|
||||
yield
|
||||
rhs = hub.make_presence_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
|
||||
binary_sensor.register_binary_sensor(rhs, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -34,7 +34,11 @@ def validate_touch_pad(value):
|
||||
return value
|
||||
|
||||
|
||||
ESP32TouchBinarySensor = binary_sensor.binary_sensor_ns.class_('ESP32TouchBinarySensor',
|
||||
binary_sensor.BinarySensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(ESP32TouchBinarySensor),
|
||||
vol.Required(CONF_PIN): validate_touch_pad,
|
||||
vol.Required(CONF_THRESHOLD): cv.uint16_t,
|
||||
cv.GenerateID(CONF_ESP32_TOUCH_ID): cv.use_variable_id(ESP32TouchComponent),
|
||||
@@ -51,3 +55,7 @@ def to_code(config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -4,14 +4,19 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN
|
||||
from esphomeyaml.helpers import App, gpio_input_pin_expression, variable, Application
|
||||
from esphomeyaml.helpers import App, gpio_input_pin_expression, variable, Application, \
|
||||
setup_component, Component
|
||||
|
||||
MakeGPIOBinarySensor = Application.MakeGPIOBinarySensor
|
||||
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))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -21,6 +26,11 @@ def to_code(config):
|
||||
rhs = App.make_gpio_binary_sensor(config[CONF_NAME], pin)
|
||||
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'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.components import binary_sensor, display
|
||||
from esphomeyaml.components.display.nextion import Nextion
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_COMPONENT_ID, CONF_NAME, CONF_PAGE_ID
|
||||
from esphomeyaml.helpers import get_variable
|
||||
|
||||
@@ -10,7 +10,11 @@ DEPENDENCIES = ['display']
|
||||
|
||||
CONF_NEXTION_ID = 'nextion_id'
|
||||
|
||||
NextionTouchComponent = display.display_ns.class_('NextionTouchComponent',
|
||||
binary_sensor.BinarySensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(NextionTouchComponent),
|
||||
vol.Required(CONF_PAGE_ID): cv.uint8_t,
|
||||
vol.Required(CONF_COMPONENT_ID): cv.uint8_t,
|
||||
cv.GenerateID(CONF_NEXTION_ID): cv.use_variable_id(Nextion)
|
||||
@@ -24,3 +28,7 @@ def to_code(config):
|
||||
rhs = hub.make_touch_component(config[CONF_NAME], config[CONF_PAGE_ID],
|
||||
config[CONF_COMPONENT_ID])
|
||||
binary_sensor.register_binary_sensor(rhs, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -27,16 +27,23 @@ def validate_uid(value):
|
||||
return value
|
||||
|
||||
|
||||
PN532BinarySensor = binary_sensor.binary_sensor_ns.class_('PN532BinarySensor',
|
||||
binary_sensor.BinarySensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(PN532BinarySensor),
|
||||
vol.Required(CONF_UID): validate_uid,
|
||||
cv.GenerateID(CONF_PN532_ID): cv.use_variable_id(PN532Component)
|
||||
}))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = None
|
||||
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], ArrayInitializer(*addr, multiline=False))
|
||||
binary_sensor.register_binary_sensor(rhs, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -9,15 +9,22 @@ DEPENDENCIES = ['rdm6300']
|
||||
|
||||
CONF_RDM6300_ID = 'rdm6300_id'
|
||||
|
||||
RDM6300BinarySensor = binary_sensor.binary_sensor_ns.class_('RDM6300BinarySensor',
|
||||
binary_sensor.BinarySensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(RDM6300BinarySensor),
|
||||
vol.Required(CONF_UID): cv.uint32_t,
|
||||
cv.GenerateID(CONF_RDM6300_ID): cv.use_variable_id(rdm6300.RDM6300Component)
|
||||
}))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = None
|
||||
for hub in get_variable(config[CONF_RDM6300_ID]):
|
||||
yield
|
||||
rhs = hub.make_card(config[CONF_NAME], config[CONF_UID])
|
||||
binary_sensor.register_binary_sensor(rhs, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -9,31 +9,34 @@ from esphomeyaml.components.remote_transmitter import RC_SWITCH_RAW_SCHEMA, \
|
||||
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_SONY, CONF_STATE
|
||||
CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \
|
||||
CONF_STATE
|
||||
from esphomeyaml.helpers import ArrayInitializer, Pvariable, get_variable
|
||||
|
||||
DEPENDENCIES = ['remote_receiver']
|
||||
|
||||
REMOTE_KEYS = [CONF_NEC, CONF_LG, CONF_SONY, CONF_PANASONIC, 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]
|
||||
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_REMOTE_RECEIVER_ID = 'remote_receiver_id'
|
||||
CONF_RECEIVER_ID = 'receiver_id'
|
||||
|
||||
RemoteReceiver = remote_ns.RemoteReceiver
|
||||
LGReceiver = remote_ns.LGReceiver
|
||||
NECReceiver = remote_ns.NECReceiver
|
||||
PanasonicReceiver = remote_ns.PanasonicReceiver
|
||||
RawReceiver = remote_ns.RawReceiver
|
||||
SonyReceiver = remote_ns.SonyReceiver
|
||||
RCSwitchRawReceiver = remote_ns.RCSwitchRawReceiver
|
||||
RCSwitchTypeAReceiver = remote_ns.RCSwitchTypeAReceiver
|
||||
RCSwitchTypeBReceiver = remote_ns.RCSwitchTypeBReceiver
|
||||
RCSwitchTypeCReceiver = remote_ns.RCSwitchTypeCReceiver
|
||||
RCSwitchTypeDReceiver = remote_ns.RCSwitchTypeDReceiver
|
||||
RemoteReceiver = remote_ns.class_('RemoteReceiver', binary_sensor.BinarySensor)
|
||||
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)
|
||||
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)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(RemoteReceiver),
|
||||
vol.Optional(CONF_LG): vol.Schema({
|
||||
vol.Required(CONF_DATA): cv.hex_uint32_t,
|
||||
vol.Optional(CONF_NBITS, default=28): vol.All(vol.Coerce(int), cv.one_of(28, 32)),
|
||||
@@ -42,6 +45,9 @@ 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_uint16_t,
|
||||
}),
|
||||
vol.Optional(CONF_SAMSUNG): vol.Schema({
|
||||
vol.Required(CONF_DATA): cv.hex_uint32_t,
|
||||
}),
|
||||
vol.Optional(CONF_SONY): vol.Schema({
|
||||
vol.Required(CONF_DATA): cv.hex_uint32_t,
|
||||
vol.Optional(CONF_NBITS, default=12): vol.All(vol.Coerce(int), cv.one_of(12, 15, 20)),
|
||||
@@ -71,10 +77,12 @@ def receiver_base(full_config):
|
||||
return NECReceiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
|
||||
elif key == CONF_PANASONIC:
|
||||
return PanasonicReceiver.new(name, config[CONF_ADDRESS], config[CONF_COMMAND])
|
||||
elif key == CONF_SAMSUNG:
|
||||
return SamsungReceiver.new(name, config[CONF_DATA])
|
||||
elif key == CONF_SONY:
|
||||
return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
|
||||
elif key == CONF_RAW:
|
||||
data = ArrayInitializer(*config[CONF_RAW], multiline=False)
|
||||
data = ArrayInitializer(*config, multiline=False)
|
||||
return RawReceiver.new(name, data)
|
||||
elif key == CONF_RC_SWITCH_RAW:
|
||||
return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
|
||||
@@ -102,7 +110,6 @@ def receiver_base(full_config):
|
||||
|
||||
|
||||
def to_code(config):
|
||||
remote = None
|
||||
for remote in get_variable(config[CONF_REMOTE_RECEIVER_ID]):
|
||||
yield
|
||||
rhs = receiver_base(config)
|
||||
@@ -112,3 +119,7 @@ def to_code(config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_REMOTE_RECEIVER'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -1,21 +1,30 @@
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME
|
||||
from esphomeyaml.helpers import App, Application, variable
|
||||
from esphomeyaml.helpers import App, Application, variable, setup_component, Component
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
MakeStatusBinarySensor = Application.MakeStatusBinarySensor
|
||||
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 = 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'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -1,22 +1,28 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import binary_sensor
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME
|
||||
from esphomeyaml.helpers import App, Application, process_lambda, variable, optional, bool_, add
|
||||
from esphomeyaml.helpers import App, Application, add, bool_, optional, process_lambda, variable, \
|
||||
setup_component, Component
|
||||
|
||||
MakeTemplateBinarySensor = Application.MakeTemplateBinarySensor
|
||||
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], [],
|
||||
@@ -26,3 +32,7 @@ def to_code(config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_TEMPLATE_BINARY_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return binary_sensor.core_to_hass_config(data, config)
|
||||
|
@@ -1,20 +1,29 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||
from esphomeyaml.components import mqtt
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_INTERNAL
|
||||
from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component, add
|
||||
from esphomeyaml.helpers import Pvariable, esphomelib_ns, setup_mqtt_component, add, \
|
||||
TemplateArguments, get_variable, Action, Nameable
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
||||
})
|
||||
|
||||
cover_ns = esphomelib_ns.namespace('cover')
|
||||
Cover = cover_ns.Cover
|
||||
MQTTCoverComponent = cover_ns.MQTTCoverComponent
|
||||
CoverState = cover_ns.CoverState
|
||||
|
||||
Cover = cover_ns.class_('Cover', Nameable)
|
||||
MQTTCoverComponent = cover_ns.class_('MQTTCoverComponent', mqtt.MQTTComponent)
|
||||
|
||||
CoverState = cover_ns.class_('CoverState')
|
||||
COVER_OPEN = cover_ns.COVER_OPEN
|
||||
COVER_CLOSED = cover_ns.COVER_CLOSED
|
||||
OpenAction = cover_ns.OpenAction
|
||||
CloseAction = cover_ns.CloseAction
|
||||
StopAction = cover_ns.StopAction
|
||||
|
||||
# Actions
|
||||
OpenAction = cover_ns.class_('OpenAction', Action)
|
||||
CloseAction = cover_ns.class_('CloseAction', Action)
|
||||
StopAction = cover_ns.class_('StopAction', Action)
|
||||
|
||||
COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(Cover),
|
||||
@@ -37,3 +46,57 @@ def setup_cover(cover_obj, mqtt_obj, config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_COVER'
|
||||
|
||||
CONF_COVER_OPEN = 'cover.open'
|
||||
COVER_OPEN_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(Cover),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_COVER_OPEN, COVER_OPEN_ACTION_SCHEMA)
|
||||
def cover_open_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_open_action(template_arg)
|
||||
type = OpenAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_COVER_CLOSE = 'cover.close'
|
||||
COVER_CLOSE_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(Cover),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_COVER_CLOSE, COVER_CLOSE_ACTION_SCHEMA)
|
||||
def cover_close_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_close_action(template_arg)
|
||||
type = CloseAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_COVER_STOP = 'cover.stop'
|
||||
COVER_STOP_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(Cover),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_COVER_STOP, COVER_STOP_ACTION_SCHEMA)
|
||||
def cover_stop_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_stop_action(template_arg)
|
||||
type = StopAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
def core_to_hass_config(data, config):
|
||||
ret = mqtt.build_hass_config(data, 'cover', config, include_state=True, include_command=True)
|
||||
if ret is None:
|
||||
return None
|
||||
return ret
|
||||
|
@@ -5,18 +5,21 @@ from esphomeyaml import automation
|
||||
from esphomeyaml.components import cover
|
||||
from esphomeyaml.const import CONF_CLOSE_ACTION, CONF_LAMBDA, CONF_MAKE_ID, CONF_NAME, \
|
||||
CONF_OPEN_ACTION, CONF_STOP_ACTION, CONF_OPTIMISTIC
|
||||
from esphomeyaml.helpers import App, Application, NoArg, add, process_lambda, variable, optional
|
||||
from esphomeyaml.helpers import App, Application, NoArg, add, process_lambda, variable, optional, \
|
||||
setup_component
|
||||
|
||||
MakeTemplateCover = Application.MakeTemplateCover
|
||||
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(),
|
||||
vol.Optional(CONF_CLOSE_ACTION): automation.validate_automation(),
|
||||
vol.Optional(CONF_STOP_ACTION): automation.validate_automation(),
|
||||
}), cv.has_at_least_one_key(CONF_LAMBDA, CONF_OPTIMISTIC))
|
||||
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):
|
||||
@@ -24,9 +27,9 @@ def to_code(config):
|
||||
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:
|
||||
template_ = None
|
||||
for template_ in process_lambda(config[CONF_LAMBDA], [],
|
||||
return_type=optional.template(cover.CoverState)):
|
||||
yield
|
||||
@@ -45,3 +48,12 @@ def to_code(config):
|
||||
|
||||
|
||||
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
|
||||
|
@@ -4,21 +4,22 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ID, CONF_PIN, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Pvariable
|
||||
from esphomeyaml.helpers import App, Pvariable, setup_component, PollingComponent
|
||||
|
||||
DallasComponent = sensor.sensor_ns.DallasComponent
|
||||
DallasComponent = sensor.sensor_ns.class_('DallasComponent', PollingComponent)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(DallasComponent),
|
||||
vol.Required(CONF_PIN): pins.input_output_pin,
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})])
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
rhs = App.make_dallas_component(conf[CONF_PIN], conf.get(CONF_UPDATE_INTERVAL))
|
||||
Pvariable(conf[CONF_ID], rhs)
|
||||
var = Pvariable(conf[CONF_ID], rhs)
|
||||
setup_component(var, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'
|
||||
|
@@ -1,9 +1,12 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import config_validation as cv, pins
|
||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
|
||||
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_RUN_CYCLES, CONF_RUN_DURATION, \
|
||||
CONF_SLEEP_DURATION, CONF_WAKEUP_PIN
|
||||
from esphomeyaml.helpers import App, Pvariable, add, gpio_input_pin_expression, esphomelib_ns
|
||||
CONF_SLEEP_DURATION, CONF_WAKEUP_PIN, CONF_MODE, CONF_PINS
|
||||
from esphomeyaml.helpers import Action, App, Component, Pvariable, TemplateArguments, add, \
|
||||
esphomelib_ns, get_variable, gpio_input_pin_expression, setup_component, global_ns, \
|
||||
StructInitializer
|
||||
|
||||
|
||||
def validate_pin_number(value):
|
||||
@@ -14,17 +17,26 @@ def validate_pin_number(value):
|
||||
return value
|
||||
|
||||
|
||||
DeepSleepComponent = esphomelib_ns.DeepSleepComponent
|
||||
EnterDeepSleepAction = esphomelib_ns.EnterDeepSleepAction
|
||||
PreventDeepSleepAction = esphomelib_ns.PreventDeepSleepAction
|
||||
DeepSleepComponent = esphomelib_ns.class_('DeepSleepComponent', Component)
|
||||
EnterDeepSleepAction = esphomelib_ns.class_('EnterDeepSleepAction', Action)
|
||||
PreventDeepSleepAction = esphomelib_ns.class_('PreventDeepSleepAction', Action)
|
||||
|
||||
WakeupPinMode = esphomelib_ns.enum('WakeupPinMode')
|
||||
WAKEUP_PIN_MODES = {
|
||||
'IGNORE': esphomelib_ns.WAKEUP_PIN_MODE_IGNORE,
|
||||
'KEEP_AWAKE': esphomelib_ns.WAKEUP_PIN_MODE_KEEP_AWAKE,
|
||||
'INVERT_WAKEUP': esphomelib_ns.WAKEUP_PIN_MODE_INVERT_WAKEUP,
|
||||
'IGNORE': WakeupPinMode.WAKEUP_PIN_MODE_IGNORE,
|
||||
'KEEP_AWAKE': WakeupPinMode.WAKEUP_PIN_MODE_KEEP_AWAKE,
|
||||
'INVERT_WAKEUP': WakeupPinMode.WAKEUP_PIN_MODE_INVERT_WAKEUP,
|
||||
}
|
||||
|
||||
esp_sleep_ext1_wakeup_mode_t = global_ns.enum('esp_sleep_ext1_wakeup_mode_t')
|
||||
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,
|
||||
}
|
||||
|
||||
CONF_WAKEUP_PIN_MODE = 'wakeup_pin_mode'
|
||||
CONF_ESP32_EXT1_WAKEUP = 'esp32_ext1_wakeup'
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(DeepSleepComponent),
|
||||
@@ -33,9 +45,14 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
validate_pin_number),
|
||||
vol.Optional(CONF_WAKEUP_PIN_MODE): vol.All(cv.only_on_esp32, vol.Upper,
|
||||
cv.one_of(*WAKEUP_PIN_MODES)),
|
||||
vol.Optional(CONF_ESP32_EXT1_WAKEUP): vol.All(cv.only_on_esp32, vol.Schema({
|
||||
vol.Required(CONF_PINS): vol.All(cv.ensure_list, [pins.shorthand_input_pin],
|
||||
[validate_pin_number]),
|
||||
vol.Required(CONF_MODE): vol.All(vol.Upper, cv.one_of(*EXT1_WAKEUP_MODES)),
|
||||
})),
|
||||
vol.Optional(CONF_RUN_CYCLES): cv.positive_int,
|
||||
vol.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -44,7 +61,6 @@ def to_code(config):
|
||||
if CONF_SLEEP_DURATION in config:
|
||||
add(deep_sleep.set_sleep_duration(config[CONF_SLEEP_DURATION]))
|
||||
if CONF_WAKEUP_PIN in config:
|
||||
pin = None
|
||||
for pin in gpio_input_pin_expression(config[CONF_WAKEUP_PIN]):
|
||||
yield
|
||||
add(deep_sleep.set_wakeup_pin(pin))
|
||||
@@ -55,5 +71,50 @@ def to_code(config):
|
||||
if CONF_RUN_DURATION in config:
|
||||
add(deep_sleep.set_run_duration(config[CONF_RUN_DURATION]))
|
||||
|
||||
if CONF_ESP32_EXT1_WAKEUP in config:
|
||||
conf = config[CONF_ESP32_EXT1_WAKEUP]
|
||||
mask = 0
|
||||
for pin in conf[CONF_PINS]:
|
||||
mask |= 1 << pin[CONF_NUMBER]
|
||||
struct = StructInitializer(
|
||||
Ext1Wakeup,
|
||||
('mask', mask),
|
||||
('wakeup_mode', EXT1_WAKEUP_MODES[conf[CONF_MODE]])
|
||||
)
|
||||
add(deep_sleep.set_ext1_wakeup(struct))
|
||||
|
||||
setup_component(deep_sleep, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_DEEP_SLEEP'
|
||||
|
||||
CONF_DEEP_SLEEP_ENTER = 'deep_sleep.enter'
|
||||
DEEP_SLEEP_ENTER_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(DeepSleepComponent),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_DEEP_SLEEP_ENTER, DEEP_SLEEP_ENTER_ACTION_SCHEMA)
|
||||
def deep_sleep_enter_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_enter_deep_sleep_action(template_arg)
|
||||
type = EnterDeepSleepAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_DEEP_SLEEP_PREVENT = 'deep_sleep.prevent'
|
||||
DEEP_SLEEP_PREVENT_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(DeepSleepComponent),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_DEEP_SLEEP_PREVENT, DEEP_SLEEP_PREVENT_ACTION_SCHEMA)
|
||||
def deep_sleep_prevent_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_prevent_deep_sleep_action(template_arg)
|
||||
type = PreventDeepSleepAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
@@ -10,7 +10,7 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
})
|
||||
|
||||
display_ns = esphomelib_ns.namespace('display')
|
||||
DisplayBuffer = display_ns.DisplayBuffer
|
||||
DisplayBuffer = display_ns.class_('DisplayBuffer')
|
||||
DisplayBufferRef = DisplayBuffer.operator('ref')
|
||||
|
||||
DISPLAY_ROTATIONS = {
|
||||
|
@@ -5,11 +5,12 @@ from esphomeyaml import pins
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.const import CONF_DATA_PINS, CONF_DIMENSIONS, CONF_ENABLE_PIN, CONF_ID, \
|
||||
CONF_LAMBDA, CONF_RS_PIN, CONF_RW_PIN
|
||||
from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, process_lambda
|
||||
from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, process_lambda, \
|
||||
setup_component, PollingComponent
|
||||
|
||||
GPIOLCDDisplay = display.display_ns.GPIOLCDDisplay
|
||||
LCDDisplay = display.display_ns.LCDDisplay
|
||||
LCDDisplay = display.display_ns.class_('LCDDisplay', PollingComponent)
|
||||
LCDDisplayRef = LCDDisplay.operator('ref')
|
||||
GPIOLCDDisplay = display.display_ns.class_('GPIOLCDDisplay', LCDDisplay)
|
||||
|
||||
|
||||
def validate_lcd_dimensions(value):
|
||||
@@ -36,7 +37,7 @@ PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Required(CONF_RS_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Optional(CONF_RW_PIN): pins.gpio_output_pin_schema,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -67,6 +68,7 @@ def to_code(config):
|
||||
add(lcd.set_writer(lambda_))
|
||||
|
||||
display.setup_display(lcd, config)
|
||||
setup_component(lcd, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_LCD_DISPLAY'
|
||||
|
@@ -1,20 +1,21 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.components.display.lcd_gpio import LCDDisplayRef, validate_lcd_dimensions
|
||||
from esphomeyaml.components import display, i2c
|
||||
from esphomeyaml.components.display.lcd_gpio import LCDDisplayRef, validate_lcd_dimensions, \
|
||||
LCDDisplay
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_DIMENSIONS, CONF_ID, CONF_LAMBDA
|
||||
from esphomeyaml.helpers import App, Pvariable, add, process_lambda
|
||||
from esphomeyaml.helpers import App, Pvariable, add, process_lambda, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
PCF8574LCDDisplay = display.display_ns.PCF8574LCDDisplay
|
||||
PCF8574LCDDisplay = display.display_ns.class_('PCF8574LCDDisplay', LCDDisplay, i2c.I2CDevice)
|
||||
|
||||
PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(PCF8574LCDDisplay),
|
||||
vol.Required(CONF_DIMENSIONS): validate_lcd_dimensions,
|
||||
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -30,6 +31,7 @@ def to_code(config):
|
||||
add(lcd.set_writer(lambda_))
|
||||
|
||||
display.setup_display(lcd, config)
|
||||
setup_component(lcd, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = ['-DUSE_LCD_DISPLAY', '-DUSE_LCD_DISPLAY_PCF8574']
|
||||
|
@@ -2,16 +2,16 @@ import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.components import display, spi
|
||||
from esphomeyaml.components.spi import SPIComponent
|
||||
from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_INTENSITY, CONF_LAMBDA, CONF_NUM_CHIPS, \
|
||||
CONF_SPI_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression, \
|
||||
process_lambda
|
||||
process_lambda, setup_component, PollingComponent
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
|
||||
MAX7219Component = display.display_ns.MAX7219Component
|
||||
MAX7219Component = display.display_ns.class_('MAX7219Component', PollingComponent, spi.SPIDevice)
|
||||
MAX7219ComponentRef = MAX7219Component.operator('ref')
|
||||
|
||||
PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
@@ -21,15 +21,15 @@ PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
|
||||
vol.Optional(CONF_NUM_CHIPS): vol.All(cv.uint8_t, vol.Range(min=1)),
|
||||
vol.Optional(CONF_INTENSITY): vol.All(cv.uint8_t, vol.Range(min=0, max=15)),
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for spi in get_variable(config[CONF_SPI_ID]):
|
||||
for spi_ in get_variable(config[CONF_SPI_ID]):
|
||||
yield
|
||||
for cs in gpio_output_pin_expression(config[CONF_CS_PIN]):
|
||||
yield
|
||||
rhs = App.make_max7219(spi, cs)
|
||||
rhs = App.make_max7219(spi_, cs)
|
||||
max7219 = Pvariable(config[CONF_ID], rhs)
|
||||
|
||||
if CONF_NUM_CHIPS in config:
|
||||
@@ -43,6 +43,7 @@ def to_code(config):
|
||||
add(max7219.set_writer(lambda_))
|
||||
|
||||
display.setup_display(max7219, config)
|
||||
setup_component(max7219, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_MAX7219'
|
||||
|
@@ -1,24 +1,26 @@
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.components import display, uart
|
||||
from esphomeyaml.components.uart import UARTComponent
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_UART_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, process_lambda
|
||||
from esphomeyaml.helpers import App, PollingComponent, Pvariable, add, get_variable, \
|
||||
process_lambda, \
|
||||
setup_component
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
|
||||
Nextion = display.display_ns.Nextion
|
||||
Nextion = display.display_ns.class_('Nextion', PollingComponent, uart.UARTDevice)
|
||||
NextionRef = Nextion.operator('ref')
|
||||
|
||||
PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(Nextion),
|
||||
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for uart in get_variable(config[CONF_UART_ID]):
|
||||
for uart_ in get_variable(config[CONF_UART_ID]):
|
||||
yield
|
||||
rhs = App.make_nextion(uart)
|
||||
rhs = App.make_nextion(uart_)
|
||||
nextion = Pvariable(config[CONF_ID], rhs)
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
@@ -27,6 +29,7 @@ def to_code(config):
|
||||
add(nextion.set_writer(lambda_))
|
||||
|
||||
display.setup_display(nextion, config)
|
||||
setup_component(nextion, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_NEXTION'
|
||||
|
@@ -4,12 +4,14 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.components.display import ssd1306_spi
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, CONF_RESET_PIN
|
||||
from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, \
|
||||
CONF_MODEL, CONF_RESET_PIN, CONF_LAMBDA
|
||||
from esphomeyaml.helpers import App, Pvariable, add, \
|
||||
gpio_output_pin_expression, process_lambda, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
I2CSSD1306 = display.display_ns.I2CSSD1306
|
||||
I2CSSD1306 = display.display_ns.class_('I2CSSD1306', ssd1306_spi.SSD1306)
|
||||
|
||||
PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(I2CSSD1306),
|
||||
@@ -17,7 +19,7 @@ PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
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)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -32,8 +34,14 @@ def to_code(config):
|
||||
add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC]))
|
||||
if CONF_ADDRESS in config:
|
||||
add(ssd.set_address(config[CONF_ADDRESS]))
|
||||
if CONF_LAMBDA in config:
|
||||
for lambda_ in process_lambda(config[CONF_LAMBDA],
|
||||
[(display.DisplayBufferRef, 'it')]):
|
||||
yield
|
||||
add(ssd.set_writer(lambda_))
|
||||
|
||||
display.setup_display(ssd, config)
|
||||
setup_component(ssd, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_SSD1306'
|
||||
|
@@ -2,23 +2,29 @@ import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.components import display, spi
|
||||
from esphomeyaml.components.spi import SPIComponent
|
||||
from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, \
|
||||
CONF_RESET_PIN, CONF_SPI_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression
|
||||
from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, \
|
||||
CONF_ID, CONF_MODEL, \
|
||||
CONF_RESET_PIN, CONF_SPI_ID, CONF_LAMBDA
|
||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, \
|
||||
gpio_output_pin_expression, process_lambda, setup_component, PollingComponent
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
|
||||
SPISSD1306 = display.display_ns.SPISSD1306
|
||||
SSD1306 = display.display_ns.class_('SSD1306', PollingComponent, display.DisplayBuffer)
|
||||
SPISSD1306 = display.display_ns.class_('SPISSD1306', SSD1306, spi.SPIDevice)
|
||||
SSD1306Model = display.display_ns.enum('SSD1306Model')
|
||||
|
||||
MODELS = {
|
||||
'SSD1306_128X32': display.display_ns.SSD1306_MODEL_128_32,
|
||||
'SSD1306_128X64': display.display_ns.SSD1306_MODEL_128_64,
|
||||
'SSD1306_96X16': display.display_ns.SSD1306_MODEL_96_16,
|
||||
'SH1106_128X32': display.display_ns.SH1106_MODEL_128_32,
|
||||
'SH1106_128X64': display.display_ns.SH1106_MODEL_128_64,
|
||||
'SH1106_96X16': display.display_ns.SH1106_MODEL_96_16,
|
||||
'SSD1306_128X32': SSD1306Model.SSD1306_MODEL_128_32,
|
||||
'SSD1306_128X64': SSD1306Model.SSD1306_MODEL_128_64,
|
||||
'SSD1306_96X16': SSD1306Model.SSD1306_MODEL_96_16,
|
||||
'SSD1306_64X48': SSD1306Model.SSD1306_MODEL_64_48,
|
||||
'SH1106_128X32': SSD1306Model.SH1106_MODEL_128_32,
|
||||
'SH1106_128X64': SSD1306Model.SH1106_MODEL_128_64,
|
||||
'SH1106_96X16': SSD1306Model.SH1106_MODEL_96_16,
|
||||
'SH1106_64X48': SSD1306Model.SH1106_MODEL_64_48,
|
||||
}
|
||||
|
||||
SSD1306_MODEL = vol.All(vol.Upper, vol.Replace(' ', '_'), cv.one_of(*MODELS))
|
||||
@@ -31,18 +37,18 @@ PLATFORM_SCHEMA = 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)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for spi in get_variable(config[CONF_SPI_ID]):
|
||||
for spi_ in get_variable(config[CONF_SPI_ID]):
|
||||
yield
|
||||
for cs in gpio_output_pin_expression(config[CONF_CS_PIN]):
|
||||
yield
|
||||
for dc in gpio_output_pin_expression(config[CONF_DC_PIN]):
|
||||
yield
|
||||
|
||||
rhs = App.make_spi_ssd1306(spi, cs, dc)
|
||||
rhs = App.make_spi_ssd1306(spi_, cs, dc)
|
||||
ssd = Pvariable(config[CONF_ID], rhs)
|
||||
add(ssd.set_model(MODELS[config[CONF_MODEL]]))
|
||||
|
||||
@@ -52,8 +58,14 @@ def to_code(config):
|
||||
add(ssd.set_reset_pin(reset))
|
||||
if CONF_EXTERNAL_VCC in config:
|
||||
add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC]))
|
||||
if CONF_LAMBDA in config:
|
||||
for lambda_ in process_lambda(config[CONF_LAMBDA],
|
||||
[(display.DisplayBufferRef, 'it')]):
|
||||
yield
|
||||
add(ssd.set_writer(lambda_))
|
||||
|
||||
display.setup_display(ssd, config)
|
||||
setup_component(ssd, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_SSD1306'
|
||||
|
@@ -2,25 +2,30 @@ import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import display
|
||||
from esphomeyaml.components import display, spi
|
||||
from esphomeyaml.components.spi import SPIComponent
|
||||
from esphomeyaml.const import CONF_BUSY_PIN, CONF_CS_PIN, CONF_DC_PIN, CONF_FULL_UPDATE_EVERY, \
|
||||
CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_input_pin_expression, \
|
||||
gpio_output_pin_expression, process_lambda
|
||||
gpio_output_pin_expression, process_lambda, setup_component, PollingComponent
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
|
||||
WaveshareEPaperTypeA = display.display_ns.WaveshareEPaperTypeA
|
||||
WaveshareEPaper = display.display_ns.WaveshareEPaper
|
||||
WaveshareEPaper = display.display_ns.class_('WaveshareEPaper',
|
||||
PollingComponent, spi.SPIDevice, display.DisplayBuffer)
|
||||
|
||||
|
||||
WaveshareEPaperTypeAModel = display.display_ns.enum('WaveshareEPaperTypeAModel')
|
||||
WaveshareEPaperTypeBModel = display.display_ns.enum('WaveshareEPaperTypeBModel')
|
||||
|
||||
MODELS = {
|
||||
'1.54in': ('a', display.display_ns.WAVESHARE_EPAPER_1_54_IN),
|
||||
'2.13in': ('a', display.display_ns.WAVESHARE_EPAPER_2_13_IN),
|
||||
'2.90in': ('a', display.display_ns.WAVESHARE_EPAPER_2_9_IN),
|
||||
'2.70in': ('b', display.display_ns.WAVESHARE_EPAPER_2_7_IN),
|
||||
'4.20in': ('b', display.display_ns.WAVESHARE_EPAPER_4_2_IN),
|
||||
'7.50in': ('b', display.display_ns.WAVESHARE_EPAPER_7_5_IN),
|
||||
'1.54in': ('a', WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_1_54_IN),
|
||||
'2.13in': ('a', WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_13_IN),
|
||||
'2.90in': ('a', WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN),
|
||||
'2.70in': ('b', WaveshareEPaperTypeBModel.WAVESHARE_EPAPER_2_7_IN),
|
||||
'4.20in': ('b', WaveshareEPaperTypeBModel.WAVESHARE_EPAPER_4_2_IN),
|
||||
'7.50in': ('b', WaveshareEPaperTypeBModel.WAVESHARE_EPAPER_7_5_IN),
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +39,7 @@ def validate_full_update_every_only_type_a(value):
|
||||
|
||||
|
||||
PLATFORM_SCHEMA = vol.All(display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(None),
|
||||
cv.GenerateID(): cv.declare_variable_id(WaveshareEPaper),
|
||||
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
|
||||
vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||
@@ -42,11 +47,11 @@ 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,
|
||||
}), validate_full_update_every_only_type_a)
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema), validate_full_update_every_only_type_a)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for spi in get_variable(config[CONF_SPI_ID]):
|
||||
for spi_ in get_variable(config[CONF_SPI_ID]):
|
||||
yield
|
||||
for cs in gpio_output_pin_expression(config[CONF_CS_PIN]):
|
||||
yield
|
||||
@@ -55,10 +60,10 @@ def to_code(config):
|
||||
|
||||
model_type, model = MODELS[config[CONF_MODEL]]
|
||||
if model_type == 'a':
|
||||
rhs = App.make_waveshare_epaper_type_a(spi, cs, dc, model)
|
||||
rhs = App.make_waveshare_epaper_type_a(spi_, cs, dc, model)
|
||||
epaper = Pvariable(config[CONF_ID], rhs, type=WaveshareEPaperTypeA)
|
||||
elif model_type == 'b':
|
||||
rhs = App.make_waveshare_epaper_type_b(spi, cs, dc, model)
|
||||
rhs = App.make_waveshare_epaper_type_b(spi_, cs, dc, model)
|
||||
epaper = Pvariable(config[CONF_ID], rhs, type=WaveshareEPaper)
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
@@ -79,6 +84,7 @@ def to_code(config):
|
||||
add(epaper.set_full_update_every(config[CONF_FULL_UPDATE_EVERY]))
|
||||
|
||||
display.setup_display(epaper, config)
|
||||
setup_component(epaper, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_WAVESHARE_EPAPER'
|
||||
|
@@ -1,5 +0,0 @@
|
||||
from esphomeyaml import config_validation as cv
|
||||
|
||||
CONFIG_SCHEMA = cv.invalid("The 'esp32_ble' component has been renamed to the 'esp32_ble_tracker' "
|
||||
"component in order to avoid confusion with the new 'esp32_ble_beacon' "
|
||||
"component.")
|
@@ -1,12 +1,13 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, ESP_PLATFORM_ESP32, CONF_UUID, CONF_TYPE
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, RawExpression, ArrayInitializer
|
||||
from esphomeyaml.const import CONF_ID, CONF_SCAN_INTERVAL, CONF_TYPE, CONF_UUID, ESP_PLATFORM_ESP32
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, Component, Pvariable, RawExpression, add, \
|
||||
esphomelib_ns, setup_component
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
ESP32BLEBeacon = esphomelib_ns.ESP32BLEBeacon
|
||||
ESP32BLEBeacon = esphomelib_ns.class_('ESP32BLEBeacon', Component)
|
||||
|
||||
CONF_MAJOR = 'major'
|
||||
CONF_MINOR = 'minor'
|
||||
@@ -18,12 +19,12 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_MAJOR): cv.uint16_t,
|
||||
vol.Optional(CONF_MINOR): cv.uint16_t,
|
||||
vol.Optional(CONF_SCAN_INTERVAL): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.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)]
|
||||
uuid_arr = [RawExpression('0x{}'.format(uuid[i:i + 2])) for i in range(0, len(uuid), 2)]
|
||||
rhs = App.make_esp32_ble_beacon(ArrayInitializer(*uuid_arr, multiline=False))
|
||||
ble = Pvariable(config[CONF_ID], rhs)
|
||||
if CONF_MAJOR in config:
|
||||
@@ -31,5 +32,7 @@ def to_code(config):
|
||||
if CONF_MINOR in config:
|
||||
add(ble.set_minor(config[CONF_MINOR]))
|
||||
|
||||
setup_component(ble, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ESP32_BLE_BEACON'
|
||||
|
@@ -1,19 +1,26 @@
|
||||
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.helpers import App, Pvariable, add, esphomelib_ns, ArrayInitializer
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, ArrayInitializer, \
|
||||
setup_component, Component
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
CONF_ESP32_BLE_ID = 'esp32_ble_id'
|
||||
ESP32BLETracker = esphomelib_ns.ESP32BLETracker
|
||||
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):
|
||||
@@ -27,5 +34,7 @@ def to_code(config):
|
||||
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'
|
||||
|
@@ -6,7 +6,7 @@ from esphomeyaml.const import CONF_ID, CONF_SETUP_MODE, CONF_IIR_FILTER, \
|
||||
CONF_SLEEP_DURATION, CONF_MEASUREMENT_DURATION, CONF_LOW_VOLTAGE_REFERENCE, \
|
||||
CONF_HIGH_VOLTAGE_REFERENCE, CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32
|
||||
from esphomeyaml.core import TimePeriod
|
||||
from esphomeyaml.helpers import App, Pvariable, add, global_ns
|
||||
from esphomeyaml.helpers import App, Pvariable, add, global_ns, setup_component, Component
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
@@ -41,7 +41,7 @@ VOLTAGE_ATTENUATION = {
|
||||
'0V': global_ns.TOUCH_HVOLT_ATTEN_0V,
|
||||
}
|
||||
|
||||
ESP32TouchComponent = binary_sensor.binary_sensor_ns.ESP32TouchComponent
|
||||
ESP32TouchComponent = binary_sensor.binary_sensor_ns.class_('ESP32TouchComponent', Component)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(ESP32TouchComponent),
|
||||
@@ -54,7 +54,7 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_LOW_VOLTAGE_REFERENCE): validate_voltage(LOW_VOLTAGE_REFERENCE),
|
||||
vol.Optional(CONF_HIGH_VOLTAGE_REFERENCE): validate_voltage(HIGH_VOLTAGE_REFERENCE),
|
||||
vol.Optional(CONF_VOLTAGE_ATTENUATION): validate_voltage(VOLTAGE_ATTENUATION),
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -80,5 +80,7 @@ def to_code(config):
|
||||
value = VOLTAGE_ATTENUATION[config[CONF_VOLTAGE_ATTENUATION]]
|
||||
add(touch.set_voltage_attenuation(value))
|
||||
|
||||
setup_component(touch, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ESP32_TOUCH_BINARY_SENSOR'
|
||||
|
@@ -1,26 +1,33 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||
from esphomeyaml.components import mqtt
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_MQTT_ID, CONF_OSCILLATION_COMMAND_TOPIC, \
|
||||
CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_INTERNAL
|
||||
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component
|
||||
CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_INTERNAL, \
|
||||
CONF_SPEED, CONF_OSCILLATING, CONF_OSCILLATION_OUTPUT, CONF_NAME
|
||||
from esphomeyaml.helpers import Application, Pvariable, add, esphomelib_ns, setup_mqtt_component, \
|
||||
TemplateArguments, get_variable, templatable, bool_, Action, Nameable, Component
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
||||
})
|
||||
|
||||
fan_ns = esphomelib_ns.namespace('fan')
|
||||
FanState = fan_ns.FanState
|
||||
MQTTFanComponent = fan_ns.MQTTFanComponent
|
||||
MakeFan = Application.MakeFan
|
||||
TurnOnAction = fan_ns.TurnOnAction
|
||||
TurnOffAction = fan_ns.TurnOffAction
|
||||
ToggleAction = fan_ns.ToggleAction
|
||||
FanSpeed = fan_ns.FanSpeed
|
||||
FAN_SPEED_OFF = fan_ns.FAN_SPEED_OFF
|
||||
FAN_SPEED_LOW = fan_ns.FAN_SPEED_LOW
|
||||
FAN_SPEED_MEDIUM = fan_ns.FAN_SPEED_MEDIUM
|
||||
FAN_SPEED_HIGH = fan_ns.FAN_SPEED_HIGH
|
||||
FanState = fan_ns.class_('FanState', Nameable, Component)
|
||||
MQTTFanComponent = fan_ns.class_('MQTTFanComponent', mqtt.MQTTComponent)
|
||||
MakeFan = Application.struct('MakeFan')
|
||||
|
||||
# Actions
|
||||
TurnOnAction = fan_ns.class_('TurnOnAction', Action)
|
||||
TurnOffAction = fan_ns.class_('TurnOffAction', Action)
|
||||
ToggleAction = fan_ns.class_('ToggleAction', Action)
|
||||
|
||||
FanSpeed = fan_ns.enum('FanSpeed')
|
||||
FAN_SPEED_OFF = FanSpeed.FAN_SPEED_OFF
|
||||
FAN_SPEED_LOW = FanSpeed.FAN_SPEED_LOW
|
||||
FAN_SPEED_MEDIUM = FanSpeed.FAN_SPEED_MEDIUM
|
||||
FAN_SPEED_HIGH = FanSpeed.FAN_SPEED_HIGH
|
||||
|
||||
FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(FanState),
|
||||
@@ -66,3 +73,74 @@ def setup_fan(fan_obj, mqtt_obj, config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_FAN'
|
||||
|
||||
|
||||
CONF_FAN_TOGGLE = 'fan.toggle'
|
||||
FAN_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(FanState),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_FAN_TOGGLE, FAN_TOGGLE_ACTION_SCHEMA)
|
||||
def fan_toggle_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_toggle_action(template_arg)
|
||||
type = ToggleAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_FAN_TURN_OFF = 'fan.turn_off'
|
||||
FAN_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(FanState),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_FAN_TURN_OFF, FAN_TURN_OFF_ACTION_SCHEMA)
|
||||
def fan_turn_off_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = TurnOffAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_FAN_TURN_ON = 'fan.turn_on'
|
||||
FAN_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(FanState),
|
||||
vol.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
||||
vol.Optional(CONF_SPEED): cv.templatable(validate_fan_speed),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_FAN_TURN_ON, FAN_TURN_ON_ACTION_SCHEMA)
|
||||
def fan_turn_on_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = TurnOnAction.template(arg_type)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_OSCILLATING in config:
|
||||
for template_ in templatable(config[CONF_OSCILLATING], arg_type, bool_):
|
||||
yield None
|
||||
add(action.set_oscillating(template_))
|
||||
if CONF_SPEED in config:
|
||||
for template_ in templatable(config[CONF_SPEED], arg_type, FanSpeed):
|
||||
yield None
|
||||
add(action.set_speed(template_))
|
||||
yield action
|
||||
|
||||
|
||||
def core_to_hass_config(data, config):
|
||||
ret = mqtt.build_hass_config(data, 'fan', config, include_state=True, include_command=True)
|
||||
if ret is None:
|
||||
return None
|
||||
if CONF_OSCILLATION_OUTPUT in config:
|
||||
default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'oscillation/state')
|
||||
ret['oscillation_state_topic'] = config.get(CONF_OSCILLATION_STATE_TOPIC, default)
|
||||
default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'oscillation/command')
|
||||
ret['oscillation_command__topic'] = config.get(CONF_OSCILLATION_COMMAND_TOPIC, default)
|
||||
return ret
|
||||
|
@@ -1,29 +1,32 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import fan
|
||||
from esphomeyaml.components import fan, output
|
||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OSCILLATION_OUTPUT, CONF_OUTPUT
|
||||
from esphomeyaml.helpers import App, add, get_variable, variable
|
||||
from esphomeyaml.helpers import App, add, get_variable, variable, setup_component
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(None),
|
||||
vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(None),
|
||||
}))
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(output.BinaryOutput),
|
||||
vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(output.BinaryOutput),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
output = None
|
||||
for output in get_variable(config[CONF_OUTPUT]):
|
||||
for output_ in get_variable(config[CONF_OUTPUT]):
|
||||
yield
|
||||
|
||||
rhs = App.make_fan(config[CONF_NAME])
|
||||
fan_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
add(fan_struct.Poutput.set_binary(output))
|
||||
add(fan_struct.Poutput.set_binary(output_))
|
||||
if CONF_OSCILLATION_OUTPUT in config:
|
||||
oscillation_output = None
|
||||
for oscillation_output in get_variable(config[CONF_OSCILLATION_OUTPUT]):
|
||||
yield
|
||||
add(fan_struct.Poutput.set_oscillation(oscillation_output))
|
||||
|
||||
fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config)
|
||||
setup_component(fan_struct.Poutput, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return fan.core_to_hass_config(data, config)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import fan
|
||||
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
|
||||
@@ -9,37 +9,46 @@ from esphomeyaml.helpers import App, add, get_variable, variable
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(fan.FAN_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(fan.MakeFan),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(None),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Optional(CONF_SPEED_STATE_TOPIC): cv.publish_topic,
|
||||
vol.Optional(CONF_SPEED_COMMAND_TOPIC): cv.subscribe_topic,
|
||||
vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(None),
|
||||
vol.Optional(CONF_OSCILLATION_OUTPUT): cv.use_variable_id(output.BinaryOutput),
|
||||
vol.Optional(CONF_SPEED): vol.Schema({
|
||||
vol.Required(CONF_LOW): cv.percentage,
|
||||
vol.Required(CONF_MEDIUM): cv.percentage,
|
||||
vol.Required(CONF_HIGH): cv.percentage,
|
||||
}),
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
output = None
|
||||
for output in get_variable(config[CONF_OUTPUT]):
|
||||
for output_ in get_variable(config[CONF_OUTPUT]):
|
||||
yield
|
||||
rhs = App.make_fan(config[CONF_NAME])
|
||||
fan_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
if CONF_SPEED in config:
|
||||
speeds = config[CONF_SPEED]
|
||||
add(fan_struct.Poutput.set_speed(output, 0.0,
|
||||
add(fan_struct.Poutput.set_speed(output_,
|
||||
speeds[CONF_LOW],
|
||||
speeds[CONF_MEDIUM],
|
||||
speeds[CONF_HIGH]))
|
||||
else:
|
||||
add(fan_struct.Poutput.set_speed(output))
|
||||
add(fan_struct.Poutput.set_speed(output_))
|
||||
|
||||
if CONF_OSCILLATION_OUTPUT in config:
|
||||
oscillation_output = None
|
||||
for oscillation_output in get_variable(config[CONF_OSCILLATION_OUTPUT]):
|
||||
yield
|
||||
add(fan_struct.Poutput.set_oscillation(oscillation_output))
|
||||
|
||||
fan.setup_fan(fan_struct.Pstate, fan_struct.Pmqtt, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
ret = fan.core_to_hass_config(data, config)
|
||||
if ret is None:
|
||||
return None
|
||||
default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'speed/state')
|
||||
ret['speed_state_topic'] = config.get(CONF_SPEED_STATE_TOPIC, default)
|
||||
default = mqtt.get_default_topic_for(data, 'fan', config[CONF_NAME], 'speed/command')
|
||||
ret['speed_command__topic'] = config.get(CONF_SPEED_COMMAND_TOPIC, default)
|
||||
return ret
|
||||
|
@@ -11,8 +11,8 @@ from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawEx
|
||||
|
||||
DEPENDENCIES = ['display']
|
||||
|
||||
Font = display.display_ns.Font
|
||||
Glyph = display.display_ns.Glyph
|
||||
Font = display.display_ns.class_('Font')
|
||||
Glyph = display.display_ns.class_('Glyph')
|
||||
|
||||
|
||||
def validate_glyphs(value):
|
||||
|
35
esphomeyaml/components/globals.py
Normal file
35
esphomeyaml/components/globals.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE
|
||||
from esphomeyaml.helpers import App, Component, Pvariable, RawExpression, TemplateArguments, add, \
|
||||
esphomelib_ns, setup_component
|
||||
|
||||
GlobalVariableComponent = esphomelib_ns.class_('GlobalVariableComponent', Component)
|
||||
|
||||
GLOBAL_VAR_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(GlobalVariableComponent),
|
||||
vol.Required(CONF_TYPE): cv.string_strict,
|
||||
vol.Optional(CONF_INITIAL_VALUE): cv.string_strict,
|
||||
vol.Optional(CONF_RESTORE_VALUE): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [GLOBAL_VAR_SCHEMA])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
type_ = RawExpression(conf[CONF_TYPE])
|
||||
template_args = TemplateArguments(type_)
|
||||
res_type = GlobalVariableComponent.template(template_args)
|
||||
initial_value = None
|
||||
if CONF_INITIAL_VALUE in conf:
|
||||
initial_value = RawExpression(conf[CONF_INITIAL_VALUE])
|
||||
rhs = App.Pmake_global_variable(template_args, initial_value)
|
||||
glob = Pvariable(conf[CONF_ID], rhs, type=res_type)
|
||||
|
||||
if conf.get(CONF_RESTORE_VALUE, False):
|
||||
hash_ = hash(conf[CONF_ID].id) % 2**32
|
||||
add(glob.set_restore_value(hash_))
|
||||
|
||||
setup_component(glob, conf)
|
@@ -4,9 +4,10 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.const import CONF_FREQUENCY, CONF_SCL, CONF_SDA, CONF_SCAN, CONF_ID, \
|
||||
CONF_RECEIVE_TIMEOUT
|
||||
from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns
|
||||
from esphomeyaml.helpers import App, add, Pvariable, esphomelib_ns, setup_component, Component
|
||||
|
||||
I2CComponent = esphomelib_ns.I2CComponent
|
||||
I2CComponent = esphomelib_ns.class_('I2CComponent', Component)
|
||||
I2CDevice = pins.I2CDevice
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(I2CComponent),
|
||||
@@ -18,7 +19,7 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_RECEIVE_TIMEOUT): cv.invalid("The receive_timeout option has been removed "
|
||||
"because timeouts are already handled by the "
|
||||
"low-level i2c interface.")
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -27,6 +28,8 @@ def to_code(config):
|
||||
if CONF_FREQUENCY in config:
|
||||
add(i2c.set_frequency(config[CONF_FREQUENCY]))
|
||||
|
||||
setup_component(i2c, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_I2C'
|
||||
|
||||
|
@@ -15,7 +15,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['display']
|
||||
|
||||
Image_ = display.display_ns.Image
|
||||
Image_ = display.display_ns.class_('Image')
|
||||
|
||||
CONF_RAW_DATA_ID = 'raw_data_id'
|
||||
|
||||
|
@@ -1,6 +0,0 @@
|
||||
import voluptuous as vol
|
||||
|
||||
|
||||
def CONFIG_SCHEMA(config):
|
||||
raise vol.Invalid("The ir_transmitter component has been renamed to "
|
||||
"remote_transmitter because of 433MHz signal support.")
|
@@ -1,43 +1,56 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
|
||||
from esphomeyaml.components import mqtt
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ALPHA, CONF_BLUE, CONF_BRIGHTNESS, CONF_COLORS, \
|
||||
CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECTS, CONF_EFFECT_ID, \
|
||||
CONF_GAMMA_CORRECT, \
|
||||
CONF_GREEN, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, CONF_NUM_LEDS, \
|
||||
CONF_RANDOM, CONF_RED, CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, CONF_UPDATE_INTERVAL, \
|
||||
CONF_WHITE, CONF_WIDTH
|
||||
from esphomeyaml.helpers import Application, ArrayInitializer, Pvariable, RawExpression, \
|
||||
StructInitializer, add, add_job, esphomelib_ns, process_lambda, setup_mqtt_component
|
||||
CONF_COLOR_TEMPERATURE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_DURATION, CONF_EFFECT, \
|
||||
CONF_EFFECTS, CONF_EFFECT_ID, CONF_FLASH_LENGTH, CONF_GAMMA_CORRECT, CONF_GREEN, CONF_ID, \
|
||||
CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, CONF_NAME, CONF_NUM_LEDS, CONF_RANDOM, CONF_RED, \
|
||||
CONF_SPEED, CONF_STATE, CONF_TRANSITION_LENGTH, CONF_UPDATE_INTERVAL, CONF_WHITE, CONF_WIDTH
|
||||
from esphomeyaml.helpers import Action, Application, ArrayInitializer, Component, Nameable, \
|
||||
Pvariable, StructInitializer, TemplateArguments, add, add_job, esphomelib_ns, float_, \
|
||||
get_variable, process_lambda, setup_mqtt_component, std_string, templatable, uint32
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
||||
})
|
||||
|
||||
# Base
|
||||
light_ns = esphomelib_ns.namespace('light')
|
||||
LightState = light_ns.LightState
|
||||
LightColorValues = light_ns.LightColorValues
|
||||
MQTTJSONLightComponent = light_ns.MQTTJSONLightComponent
|
||||
ToggleAction = light_ns.ToggleAction
|
||||
TurnOffAction = light_ns.TurnOffAction
|
||||
TurnOnAction = light_ns.TurnOnAction
|
||||
MakeLight = Application.MakeLight
|
||||
RandomLightEffect = light_ns.RandomLightEffect
|
||||
LambdaLightEffect = light_ns.LambdaLightEffect
|
||||
StrobeLightEffect = light_ns.StrobeLightEffect
|
||||
StrobeLightEffectColor = light_ns.StrobeLightEffectColor
|
||||
FlickerLightEffect = light_ns.FlickerLightEffect
|
||||
FastLEDLambdaLightEffect = light_ns.FastLEDLambdaLightEffect
|
||||
FastLEDRainbowLightEffect = light_ns.FastLEDRainbowLightEffect
|
||||
FastLEDColorWipeEffect = light_ns.FastLEDColorWipeEffect
|
||||
FastLEDColorWipeEffectColor = light_ns.FastLEDColorWipeEffectColor
|
||||
FastLEDScanEffect = light_ns.FastLEDScanEffect
|
||||
FastLEDScanEffectColor = light_ns.FastLEDScanEffectColor
|
||||
FastLEDTwinkleEffect = light_ns.FastLEDTwinkleEffect
|
||||
FastLEDRandomTwinkleEffect = light_ns.FastLEDRandomTwinkleEffect
|
||||
FastLEDFireworksEffect = light_ns.FastLEDFireworksEffect
|
||||
FastLEDFlickerEffect = light_ns.FastLEDFlickerEffect
|
||||
FastLEDLightOutputComponent = light_ns.FastLEDLightOutputComponent
|
||||
LightState = light_ns.class_('LightState', Nameable, Component)
|
||||
MakeLight = Application.struct('MakeLight')
|
||||
LightOutput = light_ns.class_('LightOutput')
|
||||
FastLEDLightOutputComponent = light_ns.class_('FastLEDLightOutputComponent', LightOutput)
|
||||
FastLEDLightOutputComponentRef = FastLEDLightOutputComponent.operator('ref')
|
||||
|
||||
# Actions
|
||||
ToggleAction = light_ns.class_('ToggleAction', Action)
|
||||
TurnOffAction = light_ns.class_('TurnOffAction', Action)
|
||||
TurnOnAction = light_ns.class_('TurnOnAction', Action)
|
||||
|
||||
LightColorValues = light_ns.class_('LightColorValues')
|
||||
|
||||
MQTTJSONLightComponent = light_ns.class_('MQTTJSONLightComponent', mqtt.MQTTComponent)
|
||||
|
||||
# Effects
|
||||
LightEffect = light_ns.class_('LightEffect')
|
||||
RandomLightEffect = light_ns.class_('RandomLightEffect', LightEffect)
|
||||
LambdaLightEffect = light_ns.class_('LambdaLightEffect', LightEffect)
|
||||
StrobeLightEffect = light_ns.class_('StrobeLightEffect', LightEffect)
|
||||
StrobeLightEffectColor = light_ns.class_('StrobeLightEffectColor', LightEffect)
|
||||
FlickerLightEffect = light_ns.class_('FlickerLightEffect', LightEffect)
|
||||
BaseFastLEDLightEffect = light_ns.class_('BaseFastLEDLightEffect', LightEffect)
|
||||
FastLEDLambdaLightEffect = light_ns.class_('FastLEDLambdaLightEffect', BaseFastLEDLightEffect)
|
||||
FastLEDRainbowLightEffect = light_ns.class_('FastLEDRainbowLightEffect', BaseFastLEDLightEffect)
|
||||
FastLEDColorWipeEffect = light_ns.class_('FastLEDColorWipeEffect', BaseFastLEDLightEffect)
|
||||
FastLEDColorWipeEffectColor = light_ns.class_('FastLEDColorWipeEffectColor', BaseFastLEDLightEffect)
|
||||
FastLEDScanEffect = light_ns.class_('FastLEDScanEffect', BaseFastLEDLightEffect)
|
||||
FastLEDScanEffectColor = light_ns.class_('FastLEDScanEffectColor', BaseFastLEDLightEffect)
|
||||
FastLEDTwinkleEffect = light_ns.class_('FastLEDTwinkleEffect', BaseFastLEDLightEffect)
|
||||
FastLEDRandomTwinkleEffect = light_ns.class_('FastLEDRandomTwinkleEffect', BaseFastLEDLightEffect)
|
||||
FastLEDFireworksEffect = light_ns.class_('FastLEDFireworksEffect', BaseFastLEDLightEffect)
|
||||
FastLEDFlickerEffect = light_ns.class_('FastLEDFlickerEffect', BaseFastLEDLightEffect)
|
||||
|
||||
CONF_STROBE = 'strobe'
|
||||
CONF_FLICKER = 'flicker'
|
||||
@@ -234,8 +247,7 @@ def build_effect(full_config):
|
||||
add(effect.set_intensity(config[CONF_INTENSITY]))
|
||||
yield effect
|
||||
elif key == CONF_FASTLED_LAMBDA:
|
||||
lambda_ = None
|
||||
args = [(RawExpression('FastLEDLightOutputComponent &'), 'it')]
|
||||
args = [(FastLEDLightOutputComponentRef, 'it')]
|
||||
for lambda_ in process_lambda(config[CONF_LAMBDA], args):
|
||||
yield None
|
||||
yield FastLEDLambdaLightEffect.new(config[CONF_NAME], lambda_, config[CONF_UPDATE_INTERVAL])
|
||||
@@ -338,3 +350,131 @@ def setup_light(light_obj, mqtt_obj, config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_LIGHT'
|
||||
|
||||
CONF_LIGHT_TOGGLE = 'light.toggle'
|
||||
LIGHT_TOGGLE_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(LightState),
|
||||
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_LIGHT_TOGGLE, LIGHT_TOGGLE_ACTION_SCHEMA)
|
||||
def light_toggle_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_toggle_action(template_arg)
|
||||
type = ToggleAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_transition_length(template_))
|
||||
yield action
|
||||
|
||||
|
||||
CONF_LIGHT_TURN_OFF = 'light.turn_off'
|
||||
LIGHT_TURN_OFF_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(LightState),
|
||||
vol.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_LIGHT_TURN_OFF, LIGHT_TURN_OFF_ACTION_SCHEMA)
|
||||
def light_turn_off_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = TurnOffAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_transition_length(template_))
|
||||
yield action
|
||||
|
||||
|
||||
CONF_LIGHT_TURN_ON = 'light.turn_on'
|
||||
LIGHT_TURN_ON_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(LightState),
|
||||
vol.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'):
|
||||
cv.templatable(cv.positive_time_period_milliseconds),
|
||||
vol.Exclusive(CONF_FLASH_LENGTH, 'transformer'):
|
||||
cv.templatable(cv.positive_time_period_milliseconds),
|
||||
vol.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
vol.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.positive_float),
|
||||
vol.Optional(CONF_EFFECT): cv.templatable(cv.string),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_LIGHT_TURN_ON, LIGHT_TURN_ON_ACTION_SCHEMA)
|
||||
def light_turn_on_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = TurnOnAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_TRANSITION_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_transition_length(template_))
|
||||
if CONF_FLASH_LENGTH in config:
|
||||
for template_ in templatable(config[CONF_FLASH_LENGTH], arg_type, uint32):
|
||||
yield None
|
||||
add(action.set_flash_length(template_))
|
||||
if CONF_BRIGHTNESS in config:
|
||||
for template_ in templatable(config[CONF_BRIGHTNESS], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_brightness(template_))
|
||||
if CONF_RED in config:
|
||||
for template_ in templatable(config[CONF_RED], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_red(template_))
|
||||
if CONF_GREEN in config:
|
||||
for template_ in templatable(config[CONF_GREEN], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_green(template_))
|
||||
if CONF_BLUE in config:
|
||||
for template_ in templatable(config[CONF_BLUE], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_blue(template_))
|
||||
if CONF_WHITE in config:
|
||||
for template_ in templatable(config[CONF_WHITE], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_white(template_))
|
||||
if CONF_COLOR_TEMPERATURE in config:
|
||||
for template_ in templatable(config[CONF_COLOR_TEMPERATURE], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_color_temperature(template_))
|
||||
if CONF_EFFECT in config:
|
||||
for template_ in templatable(config[CONF_EFFECT], arg_type, std_string):
|
||||
yield None
|
||||
add(action.set_effect(template_))
|
||||
yield action
|
||||
|
||||
|
||||
def core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=True,
|
||||
white_value=True):
|
||||
ret = mqtt.build_hass_config(data, 'light', config, include_state=True, include_command=True,
|
||||
platform='mqtt_json')
|
||||
if ret is None:
|
||||
return None
|
||||
if brightness:
|
||||
ret['brightness'] = True
|
||||
if rgb:
|
||||
ret['rgb'] = True
|
||||
if color_temp:
|
||||
ret['color_temp'] = True
|
||||
if white_value:
|
||||
ret['white_value'] = True
|
||||
for effect in config.get(CONF_EFFECTS, []):
|
||||
ret["effect"] = True
|
||||
effects = ret.setdefault("effect_list", [])
|
||||
effects.append(next(x for x in effect.values())[CONF_NAME])
|
||||
return ret
|
||||
|
@@ -1,21 +1,26 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.components import light, output
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT, CONF_EFFECTS
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.const import CONF_EFFECTS, CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT
|
||||
from esphomeyaml.helpers import App, get_variable, setup_component, variable
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(None),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(output.BinaryOutput),
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.BINARY_EFFECTS),
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
output = None
|
||||
for output in get_variable(config[CONF_OUTPUT]):
|
||||
for output_ in get_variable(config[CONF_OUTPUT]):
|
||||
yield
|
||||
rhs = App.make_binary_light(config[CONF_NAME], output)
|
||||
rhs = App.make_binary_light(config[CONF_NAME], output_)
|
||||
light_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
|
||||
setup_component(light_struct.Pstate, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=False, rgb=False, color_temp=False,
|
||||
white_value=False)
|
||||
|
@@ -1,25 +1,25 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.components import light, output
|
||||
from esphomeyaml.components.light.rgbww import validate_cold_white_colder, \
|
||||
validate_color_temperature
|
||||
from esphomeyaml.const import CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \
|
||||
CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \
|
||||
CONF_NAME, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
|
||||
vol.Required(CONF_COLD_WHITE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_WARM_WHITE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_COLD_WHITE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_WARM_WHITE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): validate_color_temperature,
|
||||
vol.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): validate_color_temperature,
|
||||
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.MONOCHROMATIC_EFFECTS),
|
||||
}), validate_cold_white_colder)
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema), validate_cold_white_colder)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -32,3 +32,9 @@ def to_code(config):
|
||||
cold_white, warm_white)
|
||||
light_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
|
||||
setup_component(light_struct.Pstate, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=False, color_temp=True,
|
||||
white_value=False)
|
||||
|
@@ -6,9 +6,9 @@ from esphomeyaml.components import light
|
||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
|
||||
from esphomeyaml.const import CONF_CHIPSET, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||
CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, CONF_NAME, CONF_NUM_LEDS, CONF_PIN, CONF_POWER_SUPPLY, \
|
||||
CONF_RGB_ORDER, CONF_EFFECTS
|
||||
CONF_RGB_ORDER, CONF_EFFECTS, CONF_COLOR_CORRECT
|
||||
from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
|
||||
get_variable, variable
|
||||
get_variable, variable, setup_component
|
||||
|
||||
TYPES = [
|
||||
'NEOPIXEL',
|
||||
@@ -53,7 +53,7 @@ def validate(value):
|
||||
return value
|
||||
|
||||
|
||||
MakeFastLEDLight = Application.MakeFastLEDLight
|
||||
MakeFastLEDLight = Application.struct('MakeFastLEDLight')
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeFastLEDLight),
|
||||
@@ -66,10 +66,11 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_RGB_ORDER): vol.All(vol.Upper, cv.one_of(*RGB_ORDERS)),
|
||||
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_COLOR_CORRECT): vol.All([cv.percentage], vol.Length(min=3, max=3)),
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent),
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.FASTLED_EFFECTS),
|
||||
}), validate)
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema), validate)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -88,12 +89,21 @@ def to_code(config):
|
||||
add(fast_led.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
|
||||
|
||||
if CONF_POWER_SUPPLY in config:
|
||||
power_supply = None
|
||||
for power_supply in get_variable(config[CONF_POWER_SUPPLY]):
|
||||
yield
|
||||
add(fast_led.set_power_supply(power_supply))
|
||||
|
||||
if CONF_COLOR_CORRECT in config:
|
||||
r, g, b = config[CONF_COLOR_CORRECT]
|
||||
add(fast_led.set_correction(r, g, b))
|
||||
|
||||
light.setup_light(make.Pstate, make.Pmqtt, config)
|
||||
setup_component(fast_led, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
|
||||
white_value=False)
|
||||
|
@@ -6,9 +6,9 @@ from esphomeyaml.components import light
|
||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
|
||||
from esphomeyaml.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, \
|
||||
CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, CONF_MAX_REFRESH_RATE, \
|
||||
CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER, CONF_EFFECTS
|
||||
CONF_NAME, CONF_NUM_LEDS, CONF_POWER_SUPPLY, CONF_RGB_ORDER, CONF_EFFECTS, CONF_COLOR_CORRECT
|
||||
from esphomeyaml.helpers import App, Application, RawExpression, TemplateArguments, add, \
|
||||
get_variable, variable
|
||||
get_variable, variable, setup_component
|
||||
|
||||
CHIPSETS = [
|
||||
'LPD8806',
|
||||
@@ -30,7 +30,7 @@ RGB_ORDERS = [
|
||||
'BGR',
|
||||
]
|
||||
|
||||
MakeFastLEDLight = Application.MakeFastLEDLight
|
||||
MakeFastLEDLight = Application.struct('MakeFastLEDLight')
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeFastLEDLight),
|
||||
@@ -44,10 +44,11 @@ PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_COLOR_CORRECT): vol.All([cv.percentage], vol.Length(min=3, max=3)),
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_POWER_SUPPLY): cv.use_variable_id(PowerSupplyComponent),
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.FASTLED_EFFECTS),
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -68,12 +69,21 @@ def to_code(config):
|
||||
add(fast_led.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
|
||||
|
||||
if CONF_POWER_SUPPLY in config:
|
||||
power_supply = None
|
||||
for power_supply in get_variable(config[CONF_POWER_SUPPLY]):
|
||||
yield
|
||||
add(fast_led.set_power_supply(power_supply))
|
||||
|
||||
light.setup_light(make.Pstate, make.Pmqtt, config)
|
||||
if CONF_COLOR_CORRECT in config:
|
||||
r, g, b = config[CONF_COLOR_CORRECT]
|
||||
add(fast_led.set_correction(r, g, b))
|
||||
|
||||
light.setup_light(make.Pstate, make.Pmqtt, config)
|
||||
setup_component(fast_led, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_FAST_LED_LIGHT'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
|
||||
white_value=False)
|
||||
|
@@ -1,24 +1,29 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.components import light, output
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, CONF_MAKE_ID, \
|
||||
CONF_NAME, CONF_OUTPUT, CONF_EFFECTS
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, \
|
||||
CONF_MAKE_ID, CONF_NAME, CONF_OUTPUT
|
||||
from esphomeyaml.helpers import App, get_variable, setup_component, variable
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(None),
|
||||
vol.Required(CONF_OUTPUT): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.MONOCHROMATIC_EFFECTS),
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
output = None
|
||||
for output in get_variable(config[CONF_OUTPUT]):
|
||||
for output_ in get_variable(config[CONF_OUTPUT]):
|
||||
yield
|
||||
rhs = App.make_monochromatic_light(config[CONF_NAME], output)
|
||||
rhs = App.make_monochromatic_light(config[CONF_NAME], output_)
|
||||
light_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
|
||||
setup_component(light_struct.Pstate, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=False, color_temp=False,
|
||||
white_value=False)
|
||||
|
@@ -1,32 +1,35 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.components import light, output
|
||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||
CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_EFFECTS
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
|
||||
vol.Required(CONF_RED): cv.use_variable_id(None),
|
||||
vol.Required(CONF_GREEN): cv.use_variable_id(None),
|
||||
vol.Required(CONF_BLUE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_RED): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_GREEN): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_BLUE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.RGB_EFFECTS),
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
red = None
|
||||
for red in get_variable(config[CONF_RED]):
|
||||
yield
|
||||
green = None
|
||||
for green in get_variable(config[CONF_GREEN]):
|
||||
yield
|
||||
blue = None
|
||||
for blue in get_variable(config[CONF_BLUE]):
|
||||
yield
|
||||
rhs = App.make_rgb_light(config[CONF_NAME], red, green, blue)
|
||||
light_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
|
||||
setup_component(light_struct.Pstate, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
|
||||
white_value=False)
|
||||
|
@@ -1,36 +1,38 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.components import light, output
|
||||
from esphomeyaml.const import CONF_BLUE, CONF_DEFAULT_TRANSITION_LENGTH, CONF_GAMMA_CORRECT, \
|
||||
CONF_GREEN, CONF_MAKE_ID, CONF_NAME, CONF_RED, CONF_WHITE, CONF_EFFECTS
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
|
||||
vol.Required(CONF_RED): cv.use_variable_id(None),
|
||||
vol.Required(CONF_GREEN): cv.use_variable_id(None),
|
||||
vol.Required(CONF_BLUE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_WHITE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_RED): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_GREEN): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_BLUE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_WHITE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.RGB_EFFECTS),
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
red = None
|
||||
for red in get_variable(config[CONF_RED]):
|
||||
yield
|
||||
green = None
|
||||
for green in get_variable(config[CONF_GREEN]):
|
||||
yield
|
||||
blue = None
|
||||
for blue in get_variable(config[CONF_BLUE]):
|
||||
yield
|
||||
white = None
|
||||
for white in get_variable(config[CONF_WHITE]):
|
||||
yield
|
||||
rhs = App.make_rgbw_light(config[CONF_NAME], red, green, blue, white)
|
||||
light_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
|
||||
setup_component(light_struct.Pstate, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=False,
|
||||
white_value=True)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import light
|
||||
from esphomeyaml.components import light, output
|
||||
from esphomeyaml.const import CONF_BLUE, CONF_COLD_WHITE, CONF_COLD_WHITE_COLOR_TEMPERATURE, \
|
||||
CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_GREEN, CONF_MAKE_ID, \
|
||||
CONF_NAME, CONF_RED, CONF_WARM_WHITE, CONF_WARM_WHITE_COLOR_TEMPERATURE
|
||||
from esphomeyaml.helpers import App, get_variable, variable
|
||||
from esphomeyaml.helpers import App, get_variable, variable, setup_component
|
||||
|
||||
|
||||
def validate_color_temperature(value):
|
||||
@@ -30,18 +30,18 @@ def validate_cold_white_colder(value):
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(light.LIGHT_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(light.MakeLight),
|
||||
vol.Required(CONF_RED): cv.use_variable_id(None),
|
||||
vol.Required(CONF_GREEN): cv.use_variable_id(None),
|
||||
vol.Required(CONF_BLUE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_COLD_WHITE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_WARM_WHITE): cv.use_variable_id(None),
|
||||
vol.Required(CONF_RED): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_GREEN): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_BLUE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_COLD_WHITE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_WARM_WHITE): cv.use_variable_id(output.FloatOutput),
|
||||
vol.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): validate_color_temperature,
|
||||
vol.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): validate_color_temperature,
|
||||
|
||||
vol.Optional(CONF_GAMMA_CORRECT): cv.positive_float,
|
||||
vol.Optional(CONF_DEFAULT_TRANSITION_LENGTH): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_EFFECTS): light.validate_effects(light.RGB_EFFECTS),
|
||||
}), validate_cold_white_colder)
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema), validate_cold_white_colder)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -60,3 +60,9 @@ def to_code(config):
|
||||
red, green, blue, cold_white, warm_white)
|
||||
light_struct = variable(config[CONF_MAKE_ID], rhs)
|
||||
light.setup_light(light_struct.Pstate, light_struct.Pmqtt, config)
|
||||
setup_component(light_struct.Pstate, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return light.core_to_hass_config(data, config, brightness=True, rgb=True, color_temp=True,
|
||||
white_value=True)
|
||||
|
@@ -1,10 +1,14 @@
|
||||
import re
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.automation import ACTION_REGISTRY, LambdaAction
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_BAUD_RATE, CONF_ID, CONF_LEVEL, CONF_LOGS, \
|
||||
CONF_TX_BUFFER_SIZE
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, global_ns
|
||||
from esphomeyaml.const import CONF_ARGS, CONF_BAUD_RATE, CONF_FORMAT, CONF_ID, CONF_LEVEL, \
|
||||
CONF_LOGS, CONF_TAG, CONF_TX_BUFFER_SIZE
|
||||
from esphomeyaml.core import ESPHomeYAMLError, Lambda
|
||||
from esphomeyaml.helpers import App, Pvariable, RawExpression, TemplateArguments, add, \
|
||||
esphomelib_ns, global_ns, process_lambda, statement, Component
|
||||
|
||||
LOG_LEVELS = {
|
||||
'NONE': global_ns.ESPHOMELIB_LOG_LEVEL_NONE,
|
||||
@@ -16,6 +20,15 @@ LOG_LEVELS = {
|
||||
'VERY_VERBOSE': global_ns.ESPHOMELIB_LOG_LEVEL_VERY_VERBOSE,
|
||||
}
|
||||
|
||||
LOG_LEVEL_TO_ESP_LOG = {
|
||||
'ERROR': global_ns.ESP_LOGE,
|
||||
'WARN': global_ns.ESP_LOGW,
|
||||
'INFO': global_ns.ESP_LOGI,
|
||||
'DEBUG': global_ns.ESP_LOGD,
|
||||
'VERBOSE': global_ns.ESP_LOGV,
|
||||
'VERY_VERBOSE': global_ns.ESP_LOGVV,
|
||||
}
|
||||
|
||||
LOG_LEVEL_SEVERITY = ['NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE', 'VERY_VERBOSE']
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
@@ -31,11 +44,11 @@ def validate_local_no_higher_than_global(value):
|
||||
return value
|
||||
|
||||
|
||||
LogComponent = esphomelib_ns.LogComponent
|
||||
LogComponent = esphomelib_ns.class_('LogComponent', Component)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(LogComponent),
|
||||
vol.Optional(CONF_BAUD_RATE): cv.positive_int,
|
||||
vol.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
|
||||
vol.Optional(CONF_TX_BUFFER_SIZE): cv.validate_bytes,
|
||||
vol.Optional(CONF_LEVEL): is_log_level,
|
||||
vol.Optional(CONF_LOGS): vol.Schema({
|
||||
@@ -59,3 +72,58 @@ def required_build_flags(config):
|
||||
if CONF_LEVEL in config:
|
||||
return u'-DESPHOMELIB_LOG_LEVEL={}'.format(str(LOG_LEVELS[config[CONF_LEVEL]]))
|
||||
return None
|
||||
|
||||
|
||||
def maybe_simple_message(schema):
|
||||
def validator(value):
|
||||
if isinstance(value, dict):
|
||||
return vol.Schema(schema)(value)
|
||||
return vol.Schema(schema)({CONF_FORMAT: value})
|
||||
|
||||
return validator
|
||||
|
||||
|
||||
def validate_printf(value):
|
||||
# https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python
|
||||
# pylint: disable=anomalous-backslash-in-string
|
||||
cfmt = u"""\
|
||||
( # start of capture group 1
|
||||
% # literal "%"
|
||||
(?: # first option
|
||||
(?:[-+0 #]{0,5}) # optional flags
|
||||
(?:\d+|\*)? # width
|
||||
(?:\.(?:\d+|\*))? # precision
|
||||
(?:h|l|ll|w|I|I32|I64)? # size
|
||||
[cCdiouxXeEfgGaAnpsSZ] # type
|
||||
) | # OR
|
||||
%%) # literal "%%"
|
||||
"""
|
||||
matches = re.findall(cfmt, value[CONF_FORMAT], flags=re.X)
|
||||
if len(matches) != len(value[CONF_ARGS]):
|
||||
raise vol.Invalid(u"Found {} printf-patterns ({}), but {} args were given!"
|
||||
u"".format(len(matches), u', '.join(matches), len(value[CONF_ARGS])))
|
||||
return value
|
||||
|
||||
|
||||
CONF_LOGGER_LOG = 'logger.log'
|
||||
LOGGER_LOG_ACTION_SCHEMA = vol.All(maybe_simple_message({
|
||||
vol.Required(CONF_FORMAT): cv.string,
|
||||
vol.Optional(CONF_ARGS, default=list): vol.All(cv.ensure_list, [cv.lambda_]),
|
||||
vol.Optional(CONF_LEVEL, default="DEBUG"): vol.All(vol.Upper, cv.one_of(*LOG_LEVEL_TO_ESP_LOG)),
|
||||
vol.Optional(CONF_TAG, default="main"): cv.string,
|
||||
}), validate_printf)
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_LOGGER_LOG, LOGGER_LOG_ACTION_SCHEMA)
|
||||
def logger_log_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
esp_log = LOG_LEVEL_TO_ESP_LOG[config[CONF_LEVEL]]
|
||||
args = [RawExpression(unicode(x)) for x in config[CONF_ARGS]]
|
||||
|
||||
text = unicode(statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args)))
|
||||
|
||||
for lambda_ in process_lambda(Lambda(text), [(arg_type, 'x')]):
|
||||
yield None
|
||||
rhs = LambdaAction.new(template_arg, lambda_)
|
||||
type = LambdaAction.template(template_arg)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
@@ -1,17 +1,23 @@
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import automation
|
||||
from esphomeyaml.automation import ACTION_REGISTRY
|
||||
from esphomeyaml.components import logger
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, CONF_DISCOVERY, \
|
||||
CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LOG_TOPIC, \
|
||||
CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, CONF_RETAIN, \
|
||||
CONF_SSL_FINGERPRINTS, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \
|
||||
CONF_WILL_MESSAGE, CONF_REBOOT_TIMEOUT, CONF_SHUTDOWN_MESSAGE
|
||||
CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, CONF_ID, CONF_KEEPALIVE, CONF_LEVEL, \
|
||||
CONF_LOG_TOPIC, CONF_ON_MESSAGE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_QOS, \
|
||||
CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, CONF_TOPIC, \
|
||||
CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, CONF_WILL_MESSAGE, CONF_ON_JSON_MESSAGE, \
|
||||
CONF_STATE_TOPIC, CONF_MQTT, CONF_ESPHOMEYAML, CONF_NAME, CONF_AVAILABILITY, \
|
||||
CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_INTERNAL
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, RawExpression, \
|
||||
StructInitializer, \
|
||||
TemplateArguments, add, esphomelib_ns, optional, std_string
|
||||
StructInitializer, TemplateArguments, add, esphomelib_ns, optional, std_string, templatable, \
|
||||
uint8, bool_, JsonObjectRef, process_lambda, JsonObjectConstRef, Component, Action, Trigger
|
||||
|
||||
|
||||
def validate_message_just_topic(value):
|
||||
@@ -32,10 +38,14 @@ MQTT_MESSAGE_SCHEMA = vol.Any(None, MQTT_MESSAGE_BASE.extend({
|
||||
}))
|
||||
|
||||
mqtt_ns = esphomelib_ns.namespace('mqtt')
|
||||
MQTTMessage = mqtt_ns.MQTTMessage
|
||||
MQTTClientComponent = mqtt_ns.MQTTClientComponent
|
||||
MQTTPublishAction = mqtt_ns.MQTTPublishAction
|
||||
MQTTMessageTrigger = mqtt_ns.MQTTMessageTrigger
|
||||
MQTTMessage = mqtt_ns.struct('MQTTMessage')
|
||||
MQTTClientComponent = mqtt_ns.class_('MQTTClientComponent', Component)
|
||||
MQTTPublishAction = mqtt_ns.class_('MQTTPublishAction', Action)
|
||||
MQTTPublishJsonAction = mqtt_ns.class_('MQTTPublishJsonAction', Action)
|
||||
MQTTMessageTrigger = mqtt_ns.class_('MQTTMessageTrigger', Trigger.template(std_string))
|
||||
MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger',
|
||||
Trigger.template(JsonObjectConstRef))
|
||||
MQTTComponent = mqtt_ns.class_('MQTTComponent', Component)
|
||||
|
||||
|
||||
def validate_broker(value):
|
||||
@@ -68,16 +78,23 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
vol.Optional(CONF_SHUTDOWN_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
vol.Optional(CONF_TOPIC_PREFIX): cv.publish_topic,
|
||||
vol.Optional(CONF_LOG_TOPIC): MQTT_MESSAGE_TEMPLATE_SCHEMA,
|
||||
vol.Optional(CONF_LOG_TOPIC): vol.Any(None, MQTT_MESSAGE_BASE.extend({
|
||||
vol.Optional(CONF_LEVEL): logger.is_log_level,
|
||||
}), validate_message_just_topic),
|
||||
vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266,
|
||||
cv.ensure_list, [validate_fingerprint]),
|
||||
vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds,
|
||||
vol.Optional(CONF_REBOOT_TIMEOUT): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
vol.Optional(CONF_ON_MESSAGE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger),
|
||||
vol.Required(CONF_TOPIC): cv.publish_topic,
|
||||
vol.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
})])
|
||||
}),
|
||||
vol.Optional(CONF_ON_JSON_MESSAGE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTJsonMessageTrigger),
|
||||
vol.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
@@ -98,14 +115,16 @@ def to_code(config):
|
||||
rhs = App.init_mqtt(config[CONF_BROKER], config[CONF_PORT],
|
||||
config[CONF_USERNAME], config[CONF_PASSWORD])
|
||||
mqtt = Pvariable(config[CONF_ID], rhs)
|
||||
|
||||
if not config.get(CONF_DISCOVERY, True):
|
||||
add(mqtt.disable_discovery())
|
||||
if CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config:
|
||||
elif CONF_DISCOVERY_RETAIN in config or CONF_DISCOVERY_PREFIX in config:
|
||||
discovery_retain = config.get(CONF_DISCOVERY_RETAIN, True)
|
||||
discovery_prefix = config.get(CONF_DISCOVERY_PREFIX, 'homeassistant')
|
||||
add(mqtt.set_discovery_info(discovery_prefix, discovery_retain))
|
||||
if CONF_TOPIC_PREFIX in config:
|
||||
add(mqtt.set_topic_prefix(config[CONF_TOPIC_PREFIX]))
|
||||
|
||||
if CONF_BIRTH_MESSAGE in config:
|
||||
birth_message = config[CONF_BIRTH_MESSAGE]
|
||||
if not birth_message:
|
||||
@@ -124,20 +143,28 @@ def to_code(config):
|
||||
add(mqtt.disable_shutdown_message())
|
||||
else:
|
||||
add(mqtt.set_shutdown_message(exp_mqtt_message(shutdown_message)))
|
||||
|
||||
if CONF_CLIENT_ID in config:
|
||||
add(mqtt.set_client_id(config[CONF_CLIENT_ID]))
|
||||
|
||||
if CONF_LOG_TOPIC in config:
|
||||
log_topic = config[CONF_LOG_TOPIC]
|
||||
if not log_topic:
|
||||
add(mqtt.disable_log_message())
|
||||
else:
|
||||
add(mqtt.set_log_message_template(exp_mqtt_message(log_topic)))
|
||||
|
||||
if CONF_LEVEL in config:
|
||||
add(mqtt.set_log_level(logger.LOG_LEVELS[config[CONF_LEVEL]]))
|
||||
|
||||
if CONF_SSL_FINGERPRINTS in config:
|
||||
for fingerprint in config[CONF_SSL_FINGERPRINTS]:
|
||||
arr = [RawExpression("0x{}".format(fingerprint[i:i + 2])) for i in range(0, 40, 2)]
|
||||
add(mqtt.add_ssl_fingerprint(ArrayInitializer(*arr, multiline=False)))
|
||||
|
||||
if CONF_KEEPALIVE in config:
|
||||
add(mqtt.set_keep_alive(config[CONF_KEEPALIVE]))
|
||||
|
||||
if CONF_REBOOT_TIMEOUT in config:
|
||||
add(mqtt.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
|
||||
|
||||
@@ -146,8 +173,138 @@ def to_code(config):
|
||||
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
|
||||
automation.build_automation(trigger, std_string, conf)
|
||||
|
||||
for conf in config.get(CONF_ON_JSON_MESSAGE, []):
|
||||
rhs = mqtt.make_json_message_trigger(conf[CONF_TOPIC], conf[CONF_QOS])
|
||||
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
|
||||
automation.build_automation(trigger, JsonObjectConstRef, conf)
|
||||
|
||||
|
||||
CONF_MQTT_PUBLISH = 'mqtt.publish'
|
||||
MQTT_PUBLISH_ACTION_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
vol.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
|
||||
vol.Optional(CONF_QOS): cv.templatable(cv.mqtt_qos),
|
||||
vol.Optional(CONF_RETAIN): cv.templatable(cv.boolean),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_MQTT_PUBLISH, MQTT_PUBLISH_ACTION_SCHEMA)
|
||||
def mqtt_publish_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
rhs = App.Pget_mqtt_client().Pmake_publish_action(template_arg)
|
||||
type = MQTTPublishAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
|
||||
yield None
|
||||
add(action.set_topic(template_))
|
||||
|
||||
for template_ in templatable(config[CONF_PAYLOAD], arg_type, std_string):
|
||||
yield None
|
||||
add(action.set_payload(template_))
|
||||
if CONF_QOS in config:
|
||||
for template_ in templatable(config[CONF_QOS], arg_type, uint8):
|
||||
yield
|
||||
add(action.set_qos(template_))
|
||||
if CONF_RETAIN in config:
|
||||
for template_ in templatable(config[CONF_RETAIN], arg_type, bool_):
|
||||
yield None
|
||||
add(action.set_retain(template_))
|
||||
yield action
|
||||
|
||||
|
||||
CONF_MQTT_PUBLISH_JSON = 'mqtt.publish_json'
|
||||
MQTT_PUBLISH_JSON_ACTION_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
vol.Required(CONF_PAYLOAD): cv.lambda_,
|
||||
vol.Optional(CONF_QOS): cv.mqtt_qos,
|
||||
vol.Optional(CONF_RETAIN): cv.boolean,
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_MQTT_PUBLISH_JSON, MQTT_PUBLISH_JSON_ACTION_SCHEMA)
|
||||
def mqtt_publish_json_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
rhs = App.Pget_mqtt_client().Pmake_publish_json_action(template_arg)
|
||||
type = MQTTPublishJsonAction.template(template_arg)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config[CONF_TOPIC], arg_type, std_string):
|
||||
yield None
|
||||
add(action.set_topic(template_))
|
||||
|
||||
for lambda_ in process_lambda(config[CONF_PAYLOAD], [(arg_type, 'x'), (JsonObjectRef, 'root')]):
|
||||
yield None
|
||||
add(action.set_payload(lambda_))
|
||||
if CONF_QOS in config:
|
||||
add(action.set_qos(config[CONF_QOS]))
|
||||
if CONF_RETAIN in config:
|
||||
add(action.set_retain(config[CONF_RETAIN]))
|
||||
yield action
|
||||
|
||||
|
||||
def required_build_flags(config):
|
||||
if CONF_SSL_FINGERPRINTS in config:
|
||||
return '-DASYNC_TCP_SSL_ENABLED=1'
|
||||
return None
|
||||
|
||||
|
||||
def get_default_topic_for(data, component_type, name, suffix):
|
||||
whitelist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
|
||||
sanitized_name = ''.join(x for x in name.lower().replace(' ', '_') if x in whitelist)
|
||||
return '{}/{}/{}/{}'.format(data.topic_prefix, component_type,
|
||||
sanitized_name, suffix)
|
||||
|
||||
|
||||
def build_hass_config(data, component_type, config, include_state=True, include_command=True,
|
||||
platform='mqtt'):
|
||||
if config.get(CONF_INTERNAL, False):
|
||||
return None
|
||||
ret = OrderedDict()
|
||||
ret['platform'] = platform
|
||||
ret['name'] = config[CONF_NAME]
|
||||
if include_state:
|
||||
default = get_default_topic_for(data, component_type, config[CONF_NAME], 'state')
|
||||
ret['state_topic'] = config.get(CONF_STATE_TOPIC, default)
|
||||
if include_command:
|
||||
default = get_default_topic_for(data, component_type, config[CONF_NAME], 'command')
|
||||
ret['command_topic'] = config.get(CONF_STATE_TOPIC, default)
|
||||
avail = config.get(CONF_AVAILABILITY, data.availability)
|
||||
if avail:
|
||||
ret['availability_topic'] = avail[CONF_TOPIC]
|
||||
payload_available = avail[CONF_PAYLOAD_AVAILABLE]
|
||||
if payload_available != 'online':
|
||||
ret['payload_available'] = payload_available
|
||||
payload_not_available = avail[CONF_PAYLOAD_NOT_AVAILABLE]
|
||||
if payload_not_available != 'offline':
|
||||
ret['payload_not_available'] = payload_not_available
|
||||
return ret
|
||||
|
||||
|
||||
class GenerateHassConfigData(object):
|
||||
def __init__(self, config):
|
||||
if 'mqtt' not in config:
|
||||
raise ESPHomeYAMLError("Cannot generate Home Assistant MQTT config if MQTT is not "
|
||||
"used!")
|
||||
mqtt = config[CONF_MQTT]
|
||||
self.topic_prefix = mqtt.get(CONF_TOPIC_PREFIX, config[CONF_ESPHOMEYAML][CONF_NAME])
|
||||
birth_message = mqtt.get(CONF_BIRTH_MESSAGE)
|
||||
if CONF_BIRTH_MESSAGE not in mqtt:
|
||||
birth_message = {
|
||||
CONF_TOPIC: self.topic_prefix + '/status',
|
||||
CONF_PAYLOAD: 'online',
|
||||
}
|
||||
will_message = mqtt.get(CONF_WILL_MESSAGE)
|
||||
if CONF_WILL_MESSAGE not in mqtt:
|
||||
will_message = {
|
||||
CONF_TOPIC: self.topic_prefix + '/status',
|
||||
CONF_PAYLOAD: 'offline'
|
||||
}
|
||||
if not birth_message or not will_message:
|
||||
self.availability = None
|
||||
elif birth_message[CONF_TOPIC] != will_message[CONF_TOPIC]:
|
||||
self.availability = None
|
||||
else:
|
||||
self.availability = {
|
||||
CONF_TOPIC: birth_message[CONF_TOPIC],
|
||||
CONF_PAYLOAD_AVAILABLE: birth_message[CONF_PAYLOAD],
|
||||
CONF_PAYLOAD_NOT_AVAILABLE: will_message[CONF_PAYLOAD],
|
||||
}
|
||||
|
52
esphomeyaml/components/my9231.py
Normal file
52
esphomeyaml/components/my9231.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.const import (CONF_DATA_PIN, CONF_CLOCK_PIN, CONF_NUM_CHANNELS,
|
||||
CONF_NUM_CHIPS, CONF_BIT_DEPTH, CONF_ID,
|
||||
CONF_UPDATE_ON_BOOT)
|
||||
from esphomeyaml.helpers import (gpio_output_pin_expression, App, Pvariable,
|
||||
add, setup_component, Component)
|
||||
|
||||
MY9231OutputComponent = output.output_ns.class_('MY9231OutputComponent', Component)
|
||||
|
||||
|
||||
MY9231_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(MY9231OutputComponent),
|
||||
vol.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Optional(CONF_NUM_CHANNELS): vol.All(vol.Coerce(int),
|
||||
vol.Range(3, 1020)),
|
||||
vol.Optional(CONF_NUM_CHIPS): vol.All(vol.Coerce(int),
|
||||
vol.Range(1, 255)),
|
||||
vol.Optional(CONF_BIT_DEPTH): vol.All(vol.Coerce(int),
|
||||
cv.one_of(8, 12, 14, 16)),
|
||||
vol.Optional(CONF_UPDATE_ON_BOOT): vol.Coerce(bool),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [MY9231_SCHEMA])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
di = None
|
||||
for di in gpio_output_pin_expression(conf[CONF_DATA_PIN]):
|
||||
yield
|
||||
dcki = None
|
||||
for dcki in gpio_output_pin_expression(conf[CONF_CLOCK_PIN]):
|
||||
yield
|
||||
rhs = App.make_my9231_component(di, dcki)
|
||||
my9231 = Pvariable(conf[CONF_ID], rhs)
|
||||
if CONF_NUM_CHANNELS in conf:
|
||||
add(my9231.set_num_channels(conf[CONF_NUM_CHANNELS]))
|
||||
if CONF_NUM_CHIPS in conf:
|
||||
add(my9231.set_num_chips(conf[CONF_NUM_CHIPS]))
|
||||
if CONF_BIT_DEPTH in conf:
|
||||
add(my9231.set_bit_depth(conf[CONF_BIT_DEPTH]))
|
||||
if CONF_UPDATE_ON_BOOT in conf:
|
||||
add(my9231.set_update(conf[CONF_UPDATE_ON_BOOT]))
|
||||
setup_component(my9231, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_MY9231_OUTPUT'
|
@@ -1,23 +1,21 @@
|
||||
import hashlib
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import core
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_OTA, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE, \
|
||||
ESP_PLATFORM_ESP32, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, Component
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
OTAComponent = esphomelib_ns.OTAComponent
|
||||
OTAComponent = esphomelib_ns.class_('OTAComponent', Component)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(OTAComponent),
|
||||
vol.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
|
||||
# TODO Num attempts + wait time
|
||||
vol.Optional(CONF_PORT): cv.port,
|
||||
vol.Optional(CONF_PASSWORD): cv.string,
|
||||
})
|
||||
@@ -27,8 +25,7 @@ def to_code(config):
|
||||
rhs = App.init_ota()
|
||||
ota = Pvariable(config[CONF_ID], rhs)
|
||||
if CONF_PASSWORD in config:
|
||||
hash_ = hashlib.md5(config[CONF_PASSWORD].encode()).hexdigest()
|
||||
add(ota.set_auth_password_hash(hash_))
|
||||
add(ota.set_auth_password(config[CONF_PASSWORD]))
|
||||
if CONF_PORT in config:
|
||||
add(ota.set_port(config[CONF_PORT]))
|
||||
if config[CONF_SAFE_MODE]:
|
||||
@@ -50,6 +47,7 @@ def get_auth(config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_OTA'
|
||||
REQUIRED_BUILD_FLAGS = '-DUSE_NEW_OTA'
|
||||
|
||||
|
||||
def lib_deps(config):
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.automation import maybe_simple_id, ACTION_REGISTRY
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components.power_supply import PowerSupplyComponent
|
||||
from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY
|
||||
from esphomeyaml.helpers import add, esphomelib_ns, get_variable
|
||||
from esphomeyaml.const import CONF_INVERTED, CONF_MAX_POWER, CONF_POWER_SUPPLY, CONF_ID, CONF_LEVEL
|
||||
from esphomeyaml.helpers import add, esphomelib_ns, get_variable, TemplateArguments, Pvariable, \
|
||||
templatable, float_, add_job, Action
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
||||
@@ -23,9 +25,13 @@ FLOAT_OUTPUT_SCHEMA = BINARY_OUTPUT_SCHEMA.extend({
|
||||
FLOAT_OUTPUT_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(FLOAT_OUTPUT_SCHEMA.schema)
|
||||
|
||||
output_ns = esphomelib_ns.namespace('output')
|
||||
TurnOffAction = output_ns.TurnOffAction
|
||||
TurnOnAction = output_ns.TurnOnAction
|
||||
SetLevelAction = output_ns.SetLevelAction
|
||||
BinaryOutput = output_ns.class_('BinaryOutput')
|
||||
FloatOutput = output_ns.class_('FloatOutput', BinaryOutput)
|
||||
|
||||
# Actions
|
||||
TurnOffAction = output_ns.class_('TurnOffAction', Action)
|
||||
TurnOnAction = output_ns.class_('TurnOnAction', Action)
|
||||
SetLevelAction = output_ns.class_('SetLevelAction', Action)
|
||||
|
||||
|
||||
def setup_output_platform_(obj, config, skip_power_supply=False):
|
||||
@@ -41,8 +47,60 @@ def setup_output_platform_(obj, config, skip_power_supply=False):
|
||||
|
||||
|
||||
def setup_output_platform(obj, config, skip_power_supply=False):
|
||||
for _ in setup_output_platform_(obj, config, skip_power_supply):
|
||||
yield
|
||||
add_job(setup_output_platform_, obj, config, skip_power_supply)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_OUTPUT'
|
||||
|
||||
|
||||
CONF_OUTPUT_TURN_ON = 'output.turn_on'
|
||||
OUTPUT_TURN_ON_ACTION = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(BinaryOutput),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_OUTPUT_TURN_ON, OUTPUT_TURN_ON_ACTION)
|
||||
def output_turn_on_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_on_action(template_arg)
|
||||
type = TurnOnAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_OUTPUT_TURN_OFF = 'output.turn_off'
|
||||
OUTPUT_TURN_OFF_ACTION = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(BinaryOutput)
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_OUTPUT_TURN_OFF, OUTPUT_TURN_OFF_ACTION)
|
||||
def output_turn_off_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_turn_off_action(template_arg)
|
||||
type = TurnOffAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
||||
|
||||
|
||||
CONF_OUTPUT_SET_LEVEL = 'output.set_level'
|
||||
OUTPUT_SET_LEVEL_ACTION = vol.Schema({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(FloatOutput),
|
||||
vol.Required(CONF_LEVEL): cv.templatable(cv.percentage),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_OUTPUT_SET_LEVEL, OUTPUT_SET_LEVEL_ACTION)
|
||||
def output_set_level_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_set_level_action(template_arg)
|
||||
type = SetLevelAction.template(arg_type)
|
||||
action = Pvariable(action_id, rhs, type=type)
|
||||
for template_ in templatable(config[CONF_LEVEL], arg_type, float_):
|
||||
yield None
|
||||
add(action.set_level(template_))
|
||||
yield action
|
||||
|
@@ -1,36 +1,41 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import pins
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266
|
||||
from esphomeyaml.core import ESPHomeYAMLError
|
||||
from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266, CONF_FREQUENCY
|
||||
from esphomeyaml.helpers import App, Component, Pvariable, gpio_output_pin_expression, \
|
||||
setup_component, add
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP8266]
|
||||
|
||||
|
||||
def valid_pwm_pin(value):
|
||||
if value[CONF_NUMBER] > 16:
|
||||
raise ESPHomeYAMLError(u"ESP8266: Only pins 0-16 support PWM.")
|
||||
num = value[CONF_NUMBER]
|
||||
cv.one_of(0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16)(num)
|
||||
return value
|
||||
|
||||
|
||||
ESP8266PWMOutput = output.output_ns.ESP8266PWMOutput
|
||||
ESP8266PWMOutput = output.output_ns.class_('ESP8266PWMOutput', output.FloatOutput, Component)
|
||||
|
||||
PLATFORM_SCHEMA = output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(ESP8266PWMOutput),
|
||||
vol.Required(CONF_PIN): vol.All(pins.internal_gpio_output_pin_schema, valid_pwm_pin),
|
||||
})
|
||||
vol.Optional(CONF_FREQUENCY): vol.All(cv.frequency, vol.Range(min=1.0e-6)),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
pin = None
|
||||
for pin in gpio_output_pin_expression(config[CONF_PIN]):
|
||||
yield
|
||||
rhs = App.make_esp8266_pwm_output(pin)
|
||||
gpio = Pvariable(config[CONF_ID], rhs)
|
||||
|
||||
if CONF_FREQUENCY in config:
|
||||
add(gpio.set_frequency(config[CONF_FREQUENCY]))
|
||||
|
||||
output.setup_output_platform(gpio, config)
|
||||
setup_component(gpio, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ESP8266_PWM_OUTPUT'
|
||||
|
@@ -4,23 +4,25 @@ from esphomeyaml import pins
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.const import CONF_ID, CONF_PIN
|
||||
from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression
|
||||
from esphomeyaml.helpers import App, Pvariable, gpio_output_pin_expression, setup_component, \
|
||||
Component
|
||||
|
||||
GPIOBinaryOutputComponent = output.output_ns.GPIOBinaryOutputComponent
|
||||
GPIOBinaryOutputComponent = output.output_ns.class_('GPIOBinaryOutputComponent',
|
||||
output.BinaryOutput, Component)
|
||||
|
||||
PLATFORM_SCHEMA = output.BINARY_OUTPUT_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(GPIOBinaryOutputComponent),
|
||||
vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
pin = None
|
||||
for pin in gpio_output_pin_expression(config[CONF_PIN]):
|
||||
yield
|
||||
rhs = App.make_gpio_output(pin)
|
||||
gpio = Pvariable(config[CONF_ID], rhs)
|
||||
output.setup_output_platform(gpio, config)
|
||||
setup_component(gpio, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_GPIO_OUTPUT'
|
||||
|
@@ -5,7 +5,7 @@ from esphomeyaml import pins
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.const import APB_CLOCK_FREQ, CONF_BIT_DEPTH, CONF_CHANNEL, CONF_FREQUENCY, \
|
||||
CONF_ID, CONF_PIN, ESP_PLATFORM_ESP32
|
||||
from esphomeyaml.helpers import App, Pvariable, add
|
||||
from esphomeyaml.helpers import App, Pvariable, add, setup_component, Component
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
@@ -19,7 +19,7 @@ def validate_frequency_bit_depth(obj):
|
||||
return obj
|
||||
|
||||
|
||||
LEDCOutputComponent = output.output_ns.LEDCOutputComponent
|
||||
LEDCOutputComponent = output.output_ns.class_('LEDCOutputComponent', output.FloatOutput, Component)
|
||||
|
||||
PLATFORM_SCHEMA = vol.All(output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(LEDCOutputComponent),
|
||||
@@ -27,7 +27,7 @@ PLATFORM_SCHEMA = vol.All(output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_FREQUENCY): cv.frequency,
|
||||
vol.Optional(CONF_BIT_DEPTH): vol.All(vol.Coerce(int), vol.Range(min=1, max=15)),
|
||||
vol.Optional(CONF_CHANNEL): vol.All(vol.Coerce(int), vol.Range(min=0, max=15))
|
||||
}), validate_frequency_bit_depth)
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema), validate_frequency_bit_depth)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -39,6 +39,7 @@ def to_code(config):
|
||||
if CONF_CHANNEL in config:
|
||||
add(ledc.set_channel(config[CONF_CHANNEL]))
|
||||
output.setup_output_platform(ledc, config)
|
||||
setup_component(ledc, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_LEDC_OUTPUT'
|
||||
|
35
esphomeyaml/components/output/my9231.py
Normal file
35
esphomeyaml/components/output/my9231.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.components.my9231 import MY9231OutputComponent
|
||||
from esphomeyaml.const import CONF_CHANNEL, CONF_ID, CONF_MY9231_ID, CONF_POWER_SUPPLY
|
||||
from esphomeyaml.helpers import Pvariable, get_variable, setup_component
|
||||
|
||||
DEPENDENCIES = ['my9231']
|
||||
|
||||
Channel = MY9231OutputComponent.class_('Channel', output.FloatOutput)
|
||||
|
||||
PLATFORM_SCHEMA = output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(Channel),
|
||||
vol.Required(CONF_CHANNEL): vol.All(vol.Coerce(int),
|
||||
vol.Range(min=0, max=65535)),
|
||||
cv.GenerateID(CONF_MY9231_ID): cv.use_variable_id(MY9231OutputComponent),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
power_supply = None
|
||||
if CONF_POWER_SUPPLY in config:
|
||||
for power_supply in get_variable(config[CONF_POWER_SUPPLY]):
|
||||
yield
|
||||
my9231 = None
|
||||
for my9231 in get_variable(config[CONF_MY9231_ID]):
|
||||
yield
|
||||
rhs = my9231.create_channel(config[CONF_CHANNEL], power_supply)
|
||||
out = Pvariable(config[CONF_ID], rhs)
|
||||
output.setup_output_platform(out, config, skip_power_supply=True)
|
||||
setup_component(out, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_MY9231_OUTPUT'
|
@@ -8,7 +8,7 @@ from esphomeyaml.helpers import Pvariable, get_variable
|
||||
|
||||
DEPENDENCIES = ['pca9685']
|
||||
|
||||
Channel = PCA9685OutputComponent.Channel
|
||||
Channel = PCA9685OutputComponent.class_('Channel', output.FloatOutput)
|
||||
|
||||
PLATFORM_SCHEMA = output.FLOAT_OUTPUT_PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(Channel),
|
||||
@@ -23,7 +23,6 @@ def to_code(config):
|
||||
if CONF_POWER_SUPPLY in config:
|
||||
for power_supply in get_variable(config[CONF_POWER_SUPPLY]):
|
||||
yield
|
||||
pca9685 = None
|
||||
for pca9685 in get_variable(config[CONF_PCA9685_ID]):
|
||||
yield
|
||||
rhs = pca9685.create_channel(config[CONF_CHANNEL], power_supply)
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import output
|
||||
from esphomeyaml.components import output, i2c
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_FREQUENCY, CONF_ID, CONF_PHASE_BALANCER
|
||||
from esphomeyaml.helpers import App, HexIntLiteral, Pvariable, add
|
||||
from esphomeyaml.helpers import App, HexIntLiteral, Pvariable, add, setup_component, Component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
PCA9685OutputComponent = output.output_ns.namespace('PCA9685OutputComponent')
|
||||
PCA9685OutputComponent = output.output_ns.class_('PCA9685OutputComponent',
|
||||
Component, i2c.I2CDevice)
|
||||
|
||||
PHASE_BALANCER_MESSAGE = ("The phase_balancer option has been removed in version 1.5.0. "
|
||||
"esphomelib will now automatically choose a suitable phase balancer.")
|
||||
@@ -19,7 +20,7 @@ PCA9685_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||
|
||||
vol.Optional(CONF_PHASE_BALANCER): cv.invalid(PHASE_BALANCER_MESSAGE),
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCA9685_SCHEMA])
|
||||
|
||||
@@ -30,6 +31,7 @@ def to_code(config):
|
||||
pca9685 = Pvariable(conf[CONF_ID], rhs)
|
||||
if CONF_ADDRESS in conf:
|
||||
add(pca9685.set_address(HexIntLiteral(conf[CONF_ADDRESS])))
|
||||
setup_component(pca9685, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_PCA9685_OUTPUT'
|
||||
|
@@ -1,19 +1,27 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import pins
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_ID, CONF_PCF8575
|
||||
from esphomeyaml.helpers import App, Pvariable, esphomelib_ns
|
||||
from esphomeyaml.helpers import App, GPIOInputPin, GPIOOutputPin, Pvariable, io_ns, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
io_ns = esphomelib_ns.namespace('io')
|
||||
PCF8574Component = io_ns.PCF8574Component
|
||||
PCF8574GPIOMode = io_ns.enum('PCF8574GPIOMode')
|
||||
PCF8675_GPIO_MODES = {
|
||||
'INPUT': PCF8574GPIOMode.PCF8574_INPUT,
|
||||
'INPUT_PULLUP': PCF8574GPIOMode.PCF8574_INPUT_PULLUP,
|
||||
'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT,
|
||||
}
|
||||
|
||||
PCF8574GPIOInputPin = io_ns.class_('PCF8574GPIOInputPin', GPIOInputPin)
|
||||
PCF8574GPIOOutputPin = io_ns.class_('PCF8574GPIOOutputPin', GPIOOutputPin)
|
||||
|
||||
PCF8574_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(PCF8574Component),
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(pins.PCF8574Component),
|
||||
vol.Optional(CONF_ADDRESS, default=0x21): cv.i2c_address,
|
||||
vol.Optional(CONF_PCF8575, default=False): cv.boolean,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA])
|
||||
|
||||
@@ -21,7 +29,8 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [PCF8574_SCHEMA])
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
rhs = App.make_pcf8574_component(conf[CONF_ADDRESS], conf[CONF_PCF8575])
|
||||
Pvariable(conf[CONF_ID], rhs)
|
||||
var = Pvariable(conf[CONF_ID], rhs)
|
||||
setup_component(var, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_PCF8574'
|
||||
|
@@ -1,34 +1,45 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml import pins, automation
|
||||
from esphomeyaml.components import binary_sensor, spi
|
||||
from esphomeyaml.components.spi import SPIComponent
|
||||
from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Pvariable, get_variable, gpio_output_pin_expression
|
||||
from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL, \
|
||||
CONF_ON_TAG, CONF_TRIGGER_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, get_variable, gpio_output_pin_expression, \
|
||||
std_string, setup_component, PollingComponent, Trigger
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
|
||||
PN532Component = binary_sensor.binary_sensor_ns.PN532Component
|
||||
PN532Component = binary_sensor.binary_sensor_ns.class_('PN532Component', PollingComponent,
|
||||
spi.SPIDevice)
|
||||
PN532Trigger = binary_sensor.binary_sensor_ns.class_('PN532Trigger', Trigger.template(std_string))
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(PN532Component),
|
||||
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
|
||||
vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})])
|
||||
vol.Optional(CONF_ON_TAG): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(PN532Trigger),
|
||||
}),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
spi = None
|
||||
for spi in get_variable(conf[CONF_SPI_ID]):
|
||||
for spi_ in get_variable(conf[CONF_SPI_ID]):
|
||||
yield
|
||||
cs = None
|
||||
for cs in gpio_output_pin_expression(conf[CONF_CS_PIN]):
|
||||
yield
|
||||
rhs = App.make_pn532_component(spi, cs, conf.get(CONF_UPDATE_INTERVAL))
|
||||
Pvariable(conf[CONF_ID], rhs)
|
||||
rhs = App.make_pn532_component(spi_, cs, conf.get(CONF_UPDATE_INTERVAL))
|
||||
pn532 = Pvariable(conf[CONF_ID], rhs)
|
||||
|
||||
for conf_ in conf.get(CONF_ON_TAG, []):
|
||||
trigger = Pvariable(conf_[CONF_TRIGGER_ID], pn532.make_trigger())
|
||||
automation.build_automation(trigger, std_string, conf_)
|
||||
|
||||
setup_component(pn532, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_PN532'
|
||||
|
@@ -3,25 +3,26 @@ import voluptuous as vol
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression, \
|
||||
setup_component, Component
|
||||
|
||||
PowerSupplyComponent = esphomelib_ns.PowerSupplyComponent
|
||||
PowerSupplyComponent = esphomelib_ns.class_('PowerSupplyComponent', Component)
|
||||
|
||||
POWER_SUPPLY_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(PowerSupplyComponent),
|
||||
vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Optional(CONF_ENABLE_TIME): cv.positive_time_period_milliseconds,
|
||||
vol.Optional(CONF_KEEP_ON_TIME): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list, [POWER_SUPPLY_SCHEMA])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
pin = None
|
||||
for pin in gpio_output_pin_expression(conf[CONF_PIN]):
|
||||
yield
|
||||
|
||||
rhs = App.make_power_supply(pin)
|
||||
psu = Pvariable(conf[CONF_ID], rhs)
|
||||
if CONF_ENABLE_TIME in conf:
|
||||
@@ -29,5 +30,7 @@ def to_code(config):
|
||||
if CONF_KEEP_ON_TIME in conf:
|
||||
add(psu.set_keep_on_time(conf[CONF_KEEP_ON_TIME]))
|
||||
|
||||
setup_component(psu, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_OUTPUT'
|
||||
|
@@ -1,28 +1,28 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import binary_sensor
|
||||
from esphomeyaml.components.uart import UARTComponent
|
||||
from esphomeyaml.components import binary_sensor, uart
|
||||
from esphomeyaml.const import CONF_ID, CONF_UART_ID
|
||||
from esphomeyaml.helpers import App, Pvariable, get_variable
|
||||
from esphomeyaml.helpers import App, Pvariable, get_variable, setup_component, Component
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
|
||||
RDM6300Component = binary_sensor.binary_sensor_ns.RDM6300Component
|
||||
RDM6300Component = binary_sensor.binary_sensor_ns.class_('RDM6300Component', Component,
|
||||
uart.UARTDevice)
|
||||
|
||||
CONFIG_SCHEMA = vol.All(cv.ensure_list_not_empty, [vol.Schema({
|
||||
cv.GenerateID(): cv.declare_variable_id(RDM6300Component),
|
||||
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
|
||||
})])
|
||||
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(uart.UARTComponent),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
uart = None
|
||||
for uart in get_variable(conf[CONF_UART_ID]):
|
||||
for uart_ in get_variable(conf[CONF_UART_ID]):
|
||||
yield
|
||||
rhs = App.make_rdm6300_component(uart)
|
||||
Pvariable(conf[CONF_ID], rhs)
|
||||
rhs = App.make_rdm6300_component(uart_)
|
||||
var = Pvariable(conf[CONF_ID], rhs)
|
||||
setup_component(var, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_RDM6300'
|
||||
|
@@ -4,19 +4,26 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.const import CONF_BUFFER_SIZE, CONF_DUMP, CONF_FILTER, CONF_ID, CONF_IDLE, \
|
||||
CONF_PIN, CONF_TOLERANCE
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_input_pin_expression
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_input_pin_expression, \
|
||||
setup_component, Component
|
||||
|
||||
remote_ns = esphomelib_ns.namespace('remote')
|
||||
|
||||
RemoteReceiverComponent = remote_ns.RemoteReceiverComponent
|
||||
RemoteControlComponentBase = remote_ns.class_('RemoteControlComponentBase')
|
||||
RemoteReceiverComponent = remote_ns.class_('RemoteReceiverComponent',
|
||||
RemoteControlComponentBase,
|
||||
Component)
|
||||
|
||||
RemoteReceiveDumper = remote_ns.class_('RemoteReceiveDumper')
|
||||
|
||||
DUMPERS = {
|
||||
'lg': remote_ns.LGDumper,
|
||||
'nec': remote_ns.NECDumper,
|
||||
'panasonic': remote_ns.PanasonicDumper,
|
||||
'raw': remote_ns.RawDumper,
|
||||
'sony': remote_ns.SonyDumper,
|
||||
'rc_switch': remote_ns.RCSwitchDumper,
|
||||
'lg': remote_ns.class_('LGDumper', RemoteReceiveDumper),
|
||||
'nec': remote_ns.class_('NECDumper', RemoteReceiveDumper),
|
||||
'panasonic': remote_ns.class_('PanasonicDumper', RemoteReceiveDumper),
|
||||
'raw': remote_ns.class_('RawDumper', RemoteReceiveDumper),
|
||||
'samsung': remote_ns.class_('SamsungDumper', RemoteReceiveDumper),
|
||||
'sony': remote_ns.class_('SonyDumper', RemoteReceiveDumper),
|
||||
'rc_switch': remote_ns.class_('RCSwitchDumper', RemoteReceiveDumper),
|
||||
}
|
||||
|
||||
|
||||
@@ -38,16 +45,16 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||
vol.Optional(CONF_BUFFER_SIZE): cv.validate_bytes,
|
||||
vol.Optional(CONF_FILTER): cv.positive_time_period_microseconds,
|
||||
vol.Optional(CONF_IDLE): cv.positive_time_period_microseconds,
|
||||
})])
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
pin = None
|
||||
for pin in gpio_input_pin_expression(conf[CONF_PIN]):
|
||||
yield
|
||||
rhs = App.make_remote_receiver_component(pin)
|
||||
receiver = Pvariable(conf[CONF_ID], rhs)
|
||||
|
||||
for dumper in conf[CONF_DUMP]:
|
||||
add(receiver.add_dumper(DUMPERS[dumper].new()))
|
||||
if CONF_TOLERANCE in conf:
|
||||
@@ -59,5 +66,7 @@ def to_code(config):
|
||||
if CONF_IDLE in conf:
|
||||
add(receiver.set_idle_us(conf[CONF_IDLE]))
|
||||
|
||||
setup_component(receiver, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_REMOTE_RECEIVER'
|
||||
|
@@ -1,17 +1,18 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components.remote_receiver import RemoteControlComponentBase, remote_ns
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_DUTY_PERCENT, CONF_CHANNEL, CONF_CODE, \
|
||||
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_ID, CONF_INVERTED, CONF_ONE, CONF_PIN, \
|
||||
CONF_PROTOCOL, CONF_PULSE_LENGTH, CONF_STATE, CONF_SYNC, CONF_ZERO
|
||||
from esphomeyaml.core import HexInt
|
||||
from esphomeyaml.helpers import App, Pvariable, add, esphomelib_ns, gpio_output_pin_expression
|
||||
from esphomeyaml.helpers import App, Component, Pvariable, add, gpio_output_pin_expression, \
|
||||
setup_component
|
||||
|
||||
remote_ns = esphomelib_ns.namespace('remote')
|
||||
|
||||
RemoteTransmitterComponent = remote_ns.RemoteTransmitterComponent
|
||||
RCSwitchProtocol = remote_ns.RCSwitchProtocol
|
||||
RemoteTransmitterComponent = remote_ns.class_('RemoteTransmitterComponent',
|
||||
RemoteControlComponentBase, Component)
|
||||
RCSwitchProtocol = remote_ns.class_('RCSwitchProtocol')
|
||||
rc_switch_protocols = remote_ns.rc_switch_protocols
|
||||
|
||||
|
||||
@@ -81,7 +82,7 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({
|
||||
vol.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
vol.Optional(CONF_CARRIER_DUTY_PERCENT): vol.All(cv.percentage_int,
|
||||
vol.Range(min=1, max=100)),
|
||||
})])
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)])
|
||||
|
||||
|
||||
def build_rc_switch_protocol(config):
|
||||
@@ -104,13 +105,15 @@ def binary_code(value):
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
pin = None
|
||||
for pin in gpio_output_pin_expression(conf[CONF_PIN]):
|
||||
yield
|
||||
rhs = App.make_remote_transmitter_component(pin)
|
||||
transmitter = Pvariable(conf[CONF_ID], rhs)
|
||||
|
||||
if CONF_CARRIER_DUTY_PERCENT in conf:
|
||||
add(transmitter.set_carrier_duty_percent(conf[CONF_CARRIER_DUTY_PERCENT]))
|
||||
|
||||
setup_component(transmitter, conf)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_REMOTE_TRANSMITTER'
|
||||
|
37
esphomeyaml/components/script.py
Normal file
37
esphomeyaml/components/script.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml import automation
|
||||
from esphomeyaml.automation import ACTION_REGISTRY, maybe_simple_id
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ID
|
||||
from esphomeyaml.helpers import NoArg, Pvariable, TemplateArguments, esphomelib_ns, get_variable, \
|
||||
Trigger, Action
|
||||
|
||||
Script = esphomelib_ns.class_('Script', Trigger.template(NoArg))
|
||||
ScriptExecuteAction = esphomelib_ns.class_('ScriptExecuteAction', Action)
|
||||
|
||||
CONFIG_SCHEMA = automation.validate_automation({
|
||||
vol.Required(CONF_ID): cv.declare_variable_id(Script),
|
||||
})
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config:
|
||||
trigger = Pvariable(conf[CONF_ID], Script.new())
|
||||
automation.build_automation(trigger, NoArg, conf)
|
||||
|
||||
|
||||
CONF_SCRIPT_EXECUTE = 'script.execute'
|
||||
SCRIPT_EXECUTE_ACTION_SCHEMA = maybe_simple_id({
|
||||
vol.Required(CONF_ID): cv.use_variable_id(Script),
|
||||
})
|
||||
|
||||
|
||||
@ACTION_REGISTRY.register(CONF_SCRIPT_EXECUTE, SCRIPT_EXECUTE_ACTION_SCHEMA)
|
||||
def script_execute_action_to_code(config, action_id, arg_type):
|
||||
template_arg = TemplateArguments(arg_type)
|
||||
for var in get_variable(config[CONF_ID]):
|
||||
yield None
|
||||
rhs = var.make_execute_action(template_arg)
|
||||
type = ScriptExecuteAction.template(arg_type)
|
||||
yield Pvariable(action_id, rhs, type=type)
|
@@ -1,15 +1,18 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import automation
|
||||
from esphomeyaml.components import mqtt
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
|
||||
CONF_DEBOUNCE, CONF_DELTA, CONF_EXPIRE_AFTER, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, \
|
||||
CONF_FILTER_NAN, CONF_FILTER_OUT, CONF_HEARTBEAT, CONF_ICON, CONF_ID, CONF_INTERNAL, \
|
||||
CONF_LAMBDA, CONF_MQTT_ID, CONF_MULTIPLY, CONF_OFFSET, CONF_ON_RAW_VALUE, CONF_ON_VALUE, \
|
||||
CONF_ON_VALUE_RANGE, CONF_OR, CONF_SEND_EVERY, CONF_SLIDING_WINDOW_MOVING_AVERAGE, \
|
||||
CONF_THROTTLE, CONF_TRIGGER_ID, CONF_UNIQUE, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, Pvariable, add, add_job, esphomelib_ns, \
|
||||
float_, process_lambda, setup_mqtt_component, templatable
|
||||
CONF_ON_VALUE_RANGE, CONF_OR, CONF_SEND_EVERY, CONF_SEND_FIRST_AT, \
|
||||
CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_THROTTLE, CONF_TRIGGER_ID, CONF_UNIQUE, \
|
||||
CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE
|
||||
from esphomeyaml.helpers import App, ArrayInitializer, Component, Nameable, PollingComponent, \
|
||||
Pvariable, Trigger, add, add_job, esphomelib_ns, float_, process_lambda, setup_mqtt_component, \
|
||||
templatable
|
||||
|
||||
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
|
||||
|
||||
@@ -20,6 +23,15 @@ def validate_recursive_filter(value):
|
||||
return FILTERS_SCHEMA(value)
|
||||
|
||||
|
||||
def validate_send_first_at(value):
|
||||
send_first_at = value.get(CONF_SEND_FIRST_AT)
|
||||
send_every = value[CONF_SEND_EVERY]
|
||||
if send_first_at is not None and send_first_at > send_every:
|
||||
raise vol.Invalid("send_first_at must be smaller than or equal to send_every! {} <= {}"
|
||||
"".format(send_first_at, send_every))
|
||||
return value
|
||||
|
||||
|
||||
FILTER_KEYS = [CONF_OFFSET, CONF_MULTIPLY, CONF_FILTER_OUT, CONF_FILTER_NAN,
|
||||
CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_LAMBDA,
|
||||
CONF_THROTTLE, CONF_DELTA, CONF_UNIQUE, CONF_HEARTBEAT, CONF_DEBOUNCE, CONF_OR]
|
||||
@@ -29,10 +41,11 @@ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
|
||||
vol.Optional(CONF_MULTIPLY): vol.Coerce(float),
|
||||
vol.Optional(CONF_FILTER_OUT): vol.Coerce(float),
|
||||
vol.Optional(CONF_FILTER_NAN): None,
|
||||
vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.Schema({
|
||||
vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.All(vol.Schema({
|
||||
vol.Required(CONF_WINDOW_SIZE): cv.positive_not_null_int,
|
||||
vol.Required(CONF_SEND_EVERY): cv.positive_not_null_int,
|
||||
}),
|
||||
vol.Optional(CONF_SEND_FIRST_AT): cv.positive_not_null_int,
|
||||
}), validate_send_first_at),
|
||||
vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): vol.Schema({
|
||||
vol.Required(CONF_ALPHA): cv.positive_float,
|
||||
vol.Required(CONF_SEND_EVERY): cv.positive_not_null_int,
|
||||
@@ -46,48 +59,54 @@ FILTERS_SCHEMA = vol.All(cv.ensure_list, [vol.All({
|
||||
vol.Optional(CONF_OR): validate_recursive_filter,
|
||||
}, cv.has_exactly_one_key(*FILTER_KEYS))])
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
# Base
|
||||
sensor_ns = esphomelib_ns.namespace('sensor')
|
||||
Sensor = sensor_ns.Sensor
|
||||
MQTTSensorComponent = sensor_ns.MQTTSensorComponent
|
||||
OffsetFilter = sensor_ns.OffsetFilter
|
||||
MultiplyFilter = sensor_ns.MultiplyFilter
|
||||
FilterOutValueFilter = sensor_ns.FilterOutValueFilter
|
||||
FilterOutNANFilter = sensor_ns.FilterOutNANFilter
|
||||
SlidingWindowMovingAverageFilter = sensor_ns.SlidingWindowMovingAverageFilter
|
||||
ExponentialMovingAverageFilter = sensor_ns.ExponentialMovingAverageFilter
|
||||
LambdaFilter = sensor_ns.LambdaFilter
|
||||
ThrottleFilter = sensor_ns.ThrottleFilter
|
||||
DeltaFilter = sensor_ns.DeltaFilter
|
||||
OrFilter = sensor_ns.OrFilter
|
||||
HeartbeatFilter = sensor_ns.HeartbeatFilter
|
||||
DebounceFilter = sensor_ns.DebounceFilter
|
||||
UniqueFilter = sensor_ns.UniqueFilter
|
||||
Sensor = sensor_ns.class_('Sensor', Nameable)
|
||||
MQTTSensorComponent = sensor_ns.class_('MQTTSensorComponent', mqtt.MQTTComponent)
|
||||
|
||||
SensorValueTrigger = sensor_ns.SensorValueTrigger
|
||||
RawSensorValueTrigger = sensor_ns.RawSensorValueTrigger
|
||||
ValueRangeTrigger = sensor_ns.ValueRangeTrigger
|
||||
PollingSensorComponent = sensor_ns.class_('PollingSensorComponent', PollingComponent, Sensor)
|
||||
EmptySensor = sensor_ns.class_('EmptySensor', Sensor)
|
||||
EmptyPollingParentSensor = sensor_ns.class_('EmptyPollingParentSensor', EmptySensor)
|
||||
|
||||
# Triggers
|
||||
SensorStateTrigger = sensor_ns.class_('SensorStateTrigger', Trigger.template(float_))
|
||||
SensorRawStateTrigger = sensor_ns.class_('SensorRawStateTrigger', Trigger.template(float_))
|
||||
ValueRangeTrigger = sensor_ns.class_('ValueRangeTrigger', Trigger.template(float_))
|
||||
|
||||
# Filters
|
||||
Filter = sensor_ns.class_('Filter')
|
||||
SlidingWindowMovingAverageFilter = sensor_ns.class_('SlidingWindowMovingAverageFilter', Filter)
|
||||
ExponentialMovingAverageFilter = sensor_ns.class_('ExponentialMovingAverageFilter', Filter)
|
||||
LambdaFilter = sensor_ns.class_('LambdaFilter', Filter)
|
||||
OffsetFilter = sensor_ns.class_('OffsetFilter', Filter)
|
||||
MultiplyFilter = sensor_ns.class_('MultiplyFilter', Filter)
|
||||
FilterOutValueFilter = sensor_ns.class_('FilterOutValueFilter', Filter)
|
||||
FilterOutNANFilter = sensor_ns.class_('FilterOutNANFilter', Filter)
|
||||
ThrottleFilter = sensor_ns.class_('ThrottleFilter', Filter)
|
||||
DebounceFilter = sensor_ns.class_('DebounceFilter', Filter, Component)
|
||||
HeartbeatFilter = sensor_ns.class_('HeartbeatFilter', Filter, Component)
|
||||
DeltaFilter = sensor_ns.class_('DeltaFilter', Filter)
|
||||
OrFilter = sensor_ns.class_('OrFilter', Filter)
|
||||
UniqueFilter = sensor_ns.class_('UniqueFilter', Filter)
|
||||
|
||||
SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTSensorComponent),
|
||||
cv.GenerateID(): cv.declare_variable_id(Sensor),
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
|
||||
vol.Optional(CONF_ICON): cv.icon,
|
||||
vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int),
|
||||
vol.Optional(CONF_EXPIRE_AFTER): vol.Any(None, cv.positive_time_period_milliseconds),
|
||||
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA,
|
||||
vol.Optional(CONF_ON_VALUE): vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(SensorValueTrigger),
|
||||
})]),
|
||||
vol.Optional(CONF_ON_RAW_VALUE): vol.All(cv.ensure_list, [automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(RawSensorValueTrigger),
|
||||
})]),
|
||||
vol.Optional(CONF_ON_VALUE_RANGE): vol.All(cv.ensure_list, [vol.All(
|
||||
automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ValueRangeTrigger),
|
||||
vol.Optional(CONF_ABOVE): vol.Coerce(float),
|
||||
vol.Optional(CONF_BELOW): vol.Coerce(float),
|
||||
}), cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))]),
|
||||
vol.Optional(CONF_ON_VALUE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(SensorStateTrigger),
|
||||
}),
|
||||
vol.Optional(CONF_ON_RAW_VALUE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(SensorRawStateTrigger),
|
||||
}),
|
||||
vol.Optional(CONF_ON_VALUE_RANGE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ValueRangeTrigger),
|
||||
vol.Optional(CONF_ABOVE): vol.Coerce(float),
|
||||
vol.Optional(CONF_BELOW): vol.Coerce(float),
|
||||
}, cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)),
|
||||
})
|
||||
|
||||
SENSOR_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(SENSOR_SCHEMA.schema)
|
||||
@@ -104,7 +123,8 @@ def setup_filter(config):
|
||||
yield FilterOutNANFilter.new()
|
||||
elif CONF_SLIDING_WINDOW_MOVING_AVERAGE in config:
|
||||
conf = config[CONF_SLIDING_WINDOW_MOVING_AVERAGE]
|
||||
yield SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY])
|
||||
yield SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY],
|
||||
conf.get(CONF_SEND_FIRST_AT))
|
||||
elif CONF_EXPONENTIAL_MOVING_AVERAGE in config:
|
||||
conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE]
|
||||
yield ExponentialMovingAverageFilter.new(conf[CONF_ALPHA], conf[CONF_SEND_EVERY])
|
||||
@@ -156,11 +176,11 @@ def setup_sensor_core_(sensor_var, mqtt_var, config):
|
||||
add(sensor_var.set_filters(filters))
|
||||
|
||||
for conf in config.get(CONF_ON_VALUE, []):
|
||||
rhs = sensor_var.make_value_trigger()
|
||||
rhs = sensor_var.make_state_trigger()
|
||||
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
|
||||
automation.build_automation(trigger, float_, conf)
|
||||
for conf in config.get(CONF_ON_RAW_VALUE, []):
|
||||
rhs = sensor_var.make_raw_value_trigger()
|
||||
rhs = sensor_var.make_raw_state_trigger()
|
||||
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
|
||||
automation.build_automation(trigger, float_, conf)
|
||||
for conf in config.get(CONF_ON_VALUE_RANGE, []):
|
||||
@@ -170,12 +190,12 @@ def setup_sensor_core_(sensor_var, mqtt_var, config):
|
||||
template_ = None
|
||||
for template_ in templatable(conf[CONF_ABOVE], float_, float_):
|
||||
yield
|
||||
trigger.set_min(template_)
|
||||
add(trigger.set_min(template_))
|
||||
if CONF_BELOW in conf:
|
||||
template_ = None
|
||||
for template_ in templatable(conf[CONF_BELOW], float_, float_):
|
||||
yield
|
||||
trigger.set_max(template_)
|
||||
add(trigger.set_max(template_))
|
||||
automation.build_automation(trigger, float_, conf)
|
||||
|
||||
if CONF_EXPIRE_AFTER in config:
|
||||
@@ -200,3 +220,18 @@ def register_sensor(var, config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_SENSOR'
|
||||
|
||||
|
||||
def core_to_hass_config(data, config):
|
||||
ret = mqtt.build_hass_config(data, 'sensor', config, include_state=True, include_command=False)
|
||||
if ret is None:
|
||||
return None
|
||||
if CONF_UNIT_OF_MEASUREMENT in config:
|
||||
ret['unit_of_measurement'] = config[CONF_UNIT_OF_MEASUREMENT]
|
||||
if CONF_EXPIRE_AFTER in config:
|
||||
expire = config[CONF_EXPIRE_AFTER]
|
||||
if expire is not None:
|
||||
ret['expire_after'] = expire.total_seconds
|
||||
if CONF_ICON in config:
|
||||
ret['icon'] = config[CONF_ICON]
|
||||
return ret
|
||||
|
@@ -5,7 +5,7 @@ from esphomeyaml import pins
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ATTENUATION, CONF_MAKE_ID, CONF_NAME, CONF_PIN, \
|
||||
CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, add, global_ns, variable
|
||||
from esphomeyaml.helpers import App, Application, add, global_ns, variable, setup_component
|
||||
|
||||
ATTENUATION_MODES = {
|
||||
'0db': global_ns.ADC_0db,
|
||||
@@ -22,14 +22,16 @@ def validate_adc_pin(value):
|
||||
return pins.analog_pin(value)
|
||||
|
||||
|
||||
MakeADCSensor = Application.MakeADCSensor
|
||||
MakeADCSensor = Application.struct('MakeADCSensor')
|
||||
ADCSensorComponent = sensor.sensor_ns.class_('ADCSensorComponent', sensor.PollingSensorComponent)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(ADCSensorComponent),
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeADCSensor),
|
||||
vol.Required(CONF_PIN): validate_adc_pin,
|
||||
vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, cv.one_of(*ATTENUATION_MODES)),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -42,7 +44,8 @@ def to_code(config):
|
||||
adc = make.Padc
|
||||
if CONF_ATTENUATION in config:
|
||||
add(adc.set_attenuation(ATTENUATION_MODES[config[CONF_ATTENUATION]]))
|
||||
sensor.setup_sensor(make.Padc, make.Pmqtt, config)
|
||||
sensor.setup_sensor(adc, make.Pmqtt, config)
|
||||
setup_component(adc, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ADC_SENSOR'
|
||||
@@ -52,3 +55,7 @@ def required_build_flags(config):
|
||||
if config[CONF_PIN] == 'VCC':
|
||||
return '-DUSE_ADC_SENSOR_VCC'
|
||||
return None
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return sensor.core_to_hass_config(data, config)
|
||||
|
@@ -9,24 +9,26 @@ from esphomeyaml.helpers import get_variable
|
||||
|
||||
DEPENDENCIES = ['ads1115']
|
||||
|
||||
ADS1115Multiplexer = sensor.sensor_ns.enum('ADS1115Multiplexer')
|
||||
MUX = {
|
||||
'A0_A1': sensor.sensor_ns.ADS1115_MULTIPLEXER_P0_N1,
|
||||
'A0_A3': sensor.sensor_ns.ADS1115_MULTIPLEXER_P0_N3,
|
||||
'A1_A3': sensor.sensor_ns.ADS1115_MULTIPLEXER_P1_N3,
|
||||
'A2_A3': sensor.sensor_ns.ADS1115_MULTIPLEXER_P2_N3,
|
||||
'A0_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P0_NG,
|
||||
'A1_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P1_NG,
|
||||
'A2_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P2_NG,
|
||||
'A3_GND': sensor.sensor_ns.ADS1115_MULTIPLEXER_P3_NG,
|
||||
'A0_A1': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
|
||||
'A0_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
|
||||
'A1_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_N3,
|
||||
'A2_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_N3,
|
||||
'A0_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_NG,
|
||||
'A1_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_NG,
|
||||
'A2_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_NG,
|
||||
'A3_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
|
||||
}
|
||||
|
||||
ADS1115Gain = sensor.sensor_ns.enum('ADS1115Gain')
|
||||
GAIN = {
|
||||
'6.144': sensor.sensor_ns.ADS1115_GAIN_6P144,
|
||||
'4.096': sensor.sensor_ns.ADS1115_GAIN_6P096,
|
||||
'2.048': sensor.sensor_ns.ADS1115_GAIN_2P048,
|
||||
'1.024': sensor.sensor_ns.ADS1115_GAIN_1P024,
|
||||
'0.512': sensor.sensor_ns.ADS1115_GAIN_0P512,
|
||||
'0.256': sensor.sensor_ns.ADS1115_GAIN_0P256,
|
||||
'6.144': ADS1115Gain.ADS1115_GAIN_6P144,
|
||||
'4.096': ADS1115Gain.ADS1115_GAIN_6P096,
|
||||
'2.048': ADS1115Gain.ADS1115_GAIN_2P048,
|
||||
'1.024': ADS1115Gain.ADS1115_GAIN_1P024,
|
||||
'0.512': ADS1115Gain.ADS1115_GAIN_0P512,
|
||||
'0.256': ADS1115Gain.ADS1115_GAIN_0P256,
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +47,10 @@ def validate_mux(value):
|
||||
return cv.one_of(*MUX)(value)
|
||||
|
||||
|
||||
ADS1115Sensor = sensor.sensor_ns.class_('ADS1115Sensor', sensor.EmptySensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(ADS1115Sensor),
|
||||
vol.Required(CONF_MULTIPLEXER): validate_mux,
|
||||
vol.Required(CONF_GAIN): validate_gain,
|
||||
cv.GenerateID(CONF_ADS1115_ID): cv.use_variable_id(ADS1115Component),
|
||||
@@ -65,3 +70,7 @@ def to_code(config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return sensor.core_to_hass_config(data, config)
|
||||
|
@@ -1,27 +1,31 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.components import sensor, i2c
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_RESOLUTION, \
|
||||
CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, add, variable
|
||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
BH1750Resolution = sensor.sensor_ns.enum('BH1750Resolution')
|
||||
BH1750_RESOLUTIONS = {
|
||||
4.0: sensor.sensor_ns.BH1750_RESOLUTION_4P0_LX,
|
||||
1.0: sensor.sensor_ns.BH1750_RESOLUTION_1P0_LX,
|
||||
0.5: sensor.sensor_ns.BH1750_RESOLUTION_0P5_LX,
|
||||
4.0: BH1750Resolution.BH1750_RESOLUTION_4P0_LX,
|
||||
1.0: BH1750Resolution.BH1750_RESOLUTION_1P0_LX,
|
||||
0.5: BH1750Resolution.BH1750_RESOLUTION_0P5_LX,
|
||||
}
|
||||
|
||||
MakeBH1750Sensor = Application.MakeBH1750Sensor
|
||||
MakeBH1750Sensor = Application.struct('MakeBH1750Sensor')
|
||||
BH1750Sensor = sensor.sensor_ns.class_('BH1750Sensor', sensor.PollingSensorComponent,
|
||||
i2c.I2CDevice)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BH1750Sensor),
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBH1750Sensor),
|
||||
vol.Optional(CONF_ADDRESS, default=0x23): cv.i2c_address,
|
||||
vol.Optional(CONF_RESOLUTION): vol.All(cv.positive_float, cv.one_of(*BH1750_RESOLUTIONS)),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -32,6 +36,11 @@ def to_code(config):
|
||||
if CONF_RESOLUTION in config:
|
||||
add(bh1750.set_resolution(BH1750_RESOLUTIONS[config[CONF_RESOLUTION]]))
|
||||
sensor.setup_sensor(bh1750, make_bh1750.Pmqtt, config)
|
||||
setup_component(bh1750, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_BH1750'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return sensor.core_to_hass_config(data, config)
|
||||
|
@@ -5,19 +5,25 @@ from esphomeyaml.components import sensor
|
||||
from esphomeyaml.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
|
||||
make_address_array
|
||||
from esphomeyaml.const import CONF_MAC_ADDRESS, CONF_NAME
|
||||
from esphomeyaml.helpers import get_variable
|
||||
from esphomeyaml.helpers import get_variable, esphomelib_ns
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
|
||||
ESP32BLERSSISensor = esphomelib_ns.class_('ESP32BLERSSISensor', sensor.Sensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(ESP32BLERSSISensor),
|
||||
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker)
|
||||
}))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = None
|
||||
for hub in get_variable(config[CONF_ESP32_BLE_ID]):
|
||||
yield
|
||||
rhs = hub.make_rssi_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
|
||||
sensor.register_sensor(rhs, config)
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return sensor.core_to_hass_config(data, config)
|
||||
|
@@ -4,42 +4,56 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_IIR_FILTER, CONF_MAKE_ID, \
|
||||
CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, add, variable
|
||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
BME280Oversampling = sensor.sensor_ns.enum('BME280Oversampling')
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
'NONE': sensor.sensor_ns.BME280_OVERSAMPLING_NONE,
|
||||
'1X': sensor.sensor_ns.BME280_OVERSAMPLING_1X,
|
||||
'2X': sensor.sensor_ns.BME280_OVERSAMPLING_2X,
|
||||
'4X': sensor.sensor_ns.BME280_OVERSAMPLING_4X,
|
||||
'8X': sensor.sensor_ns.BME280_OVERSAMPLING_8X,
|
||||
'16X': sensor.sensor_ns.BME280_OVERSAMPLING_16X,
|
||||
'NONE': BME280Oversampling.BME280_OVERSAMPLING_NONE,
|
||||
'1X': BME280Oversampling.BME280_OVERSAMPLING_1X,
|
||||
'2X': BME280Oversampling.BME280_OVERSAMPLING_2X,
|
||||
'4X': BME280Oversampling.BME280_OVERSAMPLING_4X,
|
||||
'8X': BME280Oversampling.BME280_OVERSAMPLING_8X,
|
||||
'16X': BME280Oversampling.BME280_OVERSAMPLING_16X,
|
||||
}
|
||||
|
||||
BME280IIRFilter = sensor.sensor_ns.enum('BME280IIRFilter')
|
||||
IIR_FILTER_OPTIONS = {
|
||||
'OFF': sensor.sensor_ns.BME280_IIR_FILTER_OFF,
|
||||
'2X': sensor.sensor_ns.BME280_IIR_FILTER_2X,
|
||||
'4X': sensor.sensor_ns.BME280_IIR_FILTER_4X,
|
||||
'8X': sensor.sensor_ns.BME280_IIR_FILTER_8X,
|
||||
'16X': sensor.sensor_ns.BME280_IIR_FILTER_16X,
|
||||
'OFF': BME280IIRFilter.BME280_IIR_FILTER_OFF,
|
||||
'2X': BME280IIRFilter.BME280_IIR_FILTER_2X,
|
||||
'4X': BME280IIRFilter.BME280_IIR_FILTER_4X,
|
||||
'8X': BME280IIRFilter.BME280_IIR_FILTER_8X,
|
||||
'16X': BME280IIRFilter.BME280_IIR_FILTER_16X,
|
||||
}
|
||||
|
||||
BME280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
|
||||
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)),
|
||||
})
|
||||
|
||||
MakeBME280Sensor = Application.MakeBME280Sensor
|
||||
MakeBME280Sensor = Application.struct('MakeBME280Sensor')
|
||||
BME280TemperatureSensor = sensor.sensor_ns.class_('BME280TemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BME280PressureSensor = sensor.sensor_ns.class_('BME280PressureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BME280HumiditySensor = sensor.sensor_ns.class_('BME280HumiditySensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBME280Sensor),
|
||||
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME280TemperatureSensor),
|
||||
})),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME280PressureSensor),
|
||||
})),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME280HumiditySensor),
|
||||
})),
|
||||
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, cv.one_of(*IIR_FILTER_OPTIONS)),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -69,6 +83,13 @@ def to_code(config):
|
||||
config[CONF_PRESSURE])
|
||||
sensor.setup_sensor(bme280.Pget_humidity_sensor(), make.Pmqtt_humidity,
|
||||
config[CONF_HUMIDITY])
|
||||
setup_component(bme280, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_BME280'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_PRESSURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
|
||||
|
@@ -6,43 +6,61 @@ from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_GAS_RESISTANCE, CONF_HUMIDITY, CONF_IIR_FILTER, \
|
||||
CONF_MAKE_ID, CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, \
|
||||
CONF_UPDATE_INTERVAL, CONF_HEATER, CONF_DURATION
|
||||
from esphomeyaml.helpers import App, Application, add, variable
|
||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
BME680Oversampling = sensor.sensor_ns.enum('BME680Oversampling')
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
'NONE': sensor.sensor_ns.BME680_OVERSAMPLING_NONE,
|
||||
'1X': sensor.sensor_ns.BME680_OVERSAMPLING_1X,
|
||||
'2X': sensor.sensor_ns.BME680_OVERSAMPLING_2X,
|
||||
'4X': sensor.sensor_ns.BME680_OVERSAMPLING_4X,
|
||||
'8X': sensor.sensor_ns.BME680_OVERSAMPLING_8X,
|
||||
'16X': sensor.sensor_ns.BME680_OVERSAMPLING_16X,
|
||||
'NONE': BME680Oversampling.BME680_OVERSAMPLING_NONE,
|
||||
'1X': BME680Oversampling.BME680_OVERSAMPLING_1X,
|
||||
'2X': BME680Oversampling.BME680_OVERSAMPLING_2X,
|
||||
'4X': BME680Oversampling.BME680_OVERSAMPLING_4X,
|
||||
'8X': BME680Oversampling.BME680_OVERSAMPLING_8X,
|
||||
'16X': BME680Oversampling.BME680_OVERSAMPLING_16X,
|
||||
}
|
||||
|
||||
BME680IIRFilter = sensor.sensor_ns.enum('BME680IIRFilter')
|
||||
IIR_FILTER_OPTIONS = {
|
||||
'OFF': sensor.sensor_ns.BME680_IIR_FILTER_OFF,
|
||||
'1X': sensor.sensor_ns.BME680_IIR_FILTER_1X,
|
||||
'3X': sensor.sensor_ns.BME680_IIR_FILTER_3X,
|
||||
'7X': sensor.sensor_ns.BME680_IIR_FILTER_7X,
|
||||
'15X': sensor.sensor_ns.BME680_IIR_FILTER_15X,
|
||||
'31X': sensor.sensor_ns.BME680_IIR_FILTER_31X,
|
||||
'63X': sensor.sensor_ns.BME680_IIR_FILTER_63X,
|
||||
'127X': sensor.sensor_ns.BME680_IIR_FILTER_127X,
|
||||
'OFF': BME680IIRFilter.BME680_IIR_FILTER_OFF,
|
||||
'1X': BME680IIRFilter.BME680_IIR_FILTER_1X,
|
||||
'3X': BME680IIRFilter.BME680_IIR_FILTER_3X,
|
||||
'7X': BME680IIRFilter.BME680_IIR_FILTER_7X,
|
||||
'15X': BME680IIRFilter.BME680_IIR_FILTER_15X,
|
||||
'31X': BME680IIRFilter.BME680_IIR_FILTER_31X,
|
||||
'63X': BME680IIRFilter.BME680_IIR_FILTER_63X,
|
||||
'127X': BME680IIRFilter.BME680_IIR_FILTER_127X,
|
||||
}
|
||||
|
||||
BME680_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
|
||||
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)),
|
||||
})
|
||||
|
||||
MakeBME680Sensor = Application.MakeBME680Sensor
|
||||
MakeBME680Sensor = Application.struct('MakeBME680Sensor')
|
||||
BME680TemperatureSensor = sensor.sensor_ns.class_('BME680TemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BME680PressureSensor = sensor.sensor_ns.class_('BME680PressureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BME680HumiditySensor = sensor.sensor_ns.class_('BME680HumiditySensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BME680GasResistanceSensor = sensor.sensor_ns.class_('BME680GasResistanceSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBME680Sensor),
|
||||
vol.Optional(CONF_ADDRESS, default=0x76): cv.i2c_address,
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_GAS_RESISTANCE): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME680TemperatureSensor),
|
||||
})),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME680PressureSensor),
|
||||
})),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME680HumiditySensor),
|
||||
})),
|
||||
vol.Required(CONF_GAS_RESISTANCE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BME680GasResistanceSensor),
|
||||
})),
|
||||
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, cv.one_of(*IIR_FILTER_OPTIONS)),
|
||||
vol.Optional(CONF_HEATER): vol.Any(None, vol.All(vol.Schema({
|
||||
vol.Optional(CONF_TEMPERATURE, default=320): vol.All(vol.Coerce(int), vol.Range(200, 400)),
|
||||
@@ -50,7 +68,7 @@ PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.positive_time_period_milliseconds, vol.Range(max=core.TimePeriod(milliseconds=4032)))
|
||||
}, cv.has_at_least_one_key(CONF_TEMPERATURE, CONF_DURATION)))),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -89,6 +107,14 @@ def to_code(config):
|
||||
config[CONF_HUMIDITY])
|
||||
sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), make.Pmqtt_gas_resistance,
|
||||
config[CONF_GAS_RESISTANCE])
|
||||
setup_component(bme680, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_BME680'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_PRESSURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_HUMIDITY]),
|
||||
sensor.core_to_hass_config(data, config[CONF_GAS_RESISTANCE])]
|
||||
|
@@ -4,19 +4,27 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_MAKE_ID, CONF_NAME, CONF_PRESSURE, \
|
||||
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, HexIntLiteral, add, variable
|
||||
from esphomeyaml.helpers import App, Application, HexIntLiteral, add, variable, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
MakeBMP085Sensor = Application.MakeBMP085Sensor
|
||||
MakeBMP085Sensor = Application.struct('MakeBMP085Sensor')
|
||||
BMP085TemperatureSensor = sensor.sensor_ns.class_('BMP085TemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BMP085PressureSensor = sensor.sensor_ns.class_('BMP085PressureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBMP085Sensor),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BMP085TemperatureSensor),
|
||||
})),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BMP085PressureSensor),
|
||||
})),
|
||||
vol.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -31,6 +39,12 @@ def to_code(config):
|
||||
config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(bmp.Pbmp.Pget_pressure_sensor(), bmp.Pmqtt_pressure,
|
||||
config[CONF_PRESSURE])
|
||||
setup_component(bmp.Pbmp, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_BMP085_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_PRESSURE])]
|
||||
|
@@ -4,41 +4,51 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_ADDRESS, CONF_IIR_FILTER, CONF_MAKE_ID, \
|
||||
CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, add, variable
|
||||
from esphomeyaml.helpers import App, Application, add, variable, setup_component
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
BMP280Oversampling = sensor.sensor_ns.enum('BMP280Oversampling')
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
'NONE': sensor.sensor_ns.BMP280_OVERSAMPLING_NONE,
|
||||
'1X': sensor.sensor_ns.BMP280_OVERSAMPLING_1X,
|
||||
'2X': sensor.sensor_ns.BMP280_OVERSAMPLING_2X,
|
||||
'4X': sensor.sensor_ns.BMP280_OVERSAMPLING_4X,
|
||||
'8X': sensor.sensor_ns.BMP280_OVERSAMPLING_8X,
|
||||
'16X': sensor.sensor_ns.BMP280_OVERSAMPLING_16X,
|
||||
'NONE': BMP280Oversampling.BMP280_OVERSAMPLING_NONE,
|
||||
'1X': BMP280Oversampling.BMP280_OVERSAMPLING_1X,
|
||||
'2X': BMP280Oversampling.BMP280_OVERSAMPLING_2X,
|
||||
'4X': BMP280Oversampling.BMP280_OVERSAMPLING_4X,
|
||||
'8X': BMP280Oversampling.BMP280_OVERSAMPLING_8X,
|
||||
'16X': BMP280Oversampling.BMP280_OVERSAMPLING_16X,
|
||||
}
|
||||
|
||||
BMP280IIRFilter = sensor.sensor_ns.enum('BMP280IIRFilter')
|
||||
IIR_FILTER_OPTIONS = {
|
||||
'OFF': sensor.sensor_ns.BMP280_IIR_FILTER_OFF,
|
||||
'2X': sensor.sensor_ns.BMP280_IIR_FILTER_2X,
|
||||
'4X': sensor.sensor_ns.BMP280_IIR_FILTER_4X,
|
||||
'8X': sensor.sensor_ns.BMP280_IIR_FILTER_8X,
|
||||
'16X': sensor.sensor_ns.BMP280_IIR_FILTER_16X,
|
||||
'OFF': BMP280IIRFilter.BMP280_IIR_FILTER_OFF,
|
||||
'2X': BMP280IIRFilter.BMP280_IIR_FILTER_2X,
|
||||
'4X': BMP280IIRFilter.BMP280_IIR_FILTER_4X,
|
||||
'8X': BMP280IIRFilter.BMP280_IIR_FILTER_8X,
|
||||
'16X': BMP280IIRFilter.BMP280_IIR_FILTER_16X,
|
||||
}
|
||||
|
||||
BMP280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
|
||||
vol.Optional(CONF_OVERSAMPLING): vol.All(vol.Upper, cv.one_of(*OVERSAMPLING_OPTIONS)),
|
||||
})
|
||||
|
||||
MakeBMP280Sensor = Application.MakeBMP280Sensor
|
||||
MakeBMP280Sensor = Application.struct('MakeBMP280Sensor')
|
||||
BMP280TemperatureSensor = sensor.sensor_ns.class_('BMP280TemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
BMP280PressureSensor = sensor.sensor_ns.class_('BMP280PressureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeBMP280Sensor),
|
||||
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BMP280TemperatureSensor),
|
||||
})),
|
||||
vol.Required(CONF_PRESSURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(BMP280PressureSensor),
|
||||
})),
|
||||
vol.Optional(CONF_IIR_FILTER): vol.All(vol.Upper, cv.one_of(*IIR_FILTER_OPTIONS)),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@@ -62,6 +72,12 @@ def to_code(config):
|
||||
config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(bmp280.Pget_pressure_sensor(), make.Pmqtt_pressure,
|
||||
config[CONF_PRESSURE])
|
||||
setup_component(bmp280, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_BMP280'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_PRESSURE])]
|
||||
|
64
esphomeyaml/components/sensor/cse7766.py
Normal file
64
esphomeyaml/components/sensor/cse7766.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import voluptuous as vol
|
||||
|
||||
from esphomeyaml.components import sensor, uart
|
||||
from esphomeyaml.components.uart import UARTComponent
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.const import CONF_CURRENT, CONF_ID, CONF_NAME, CONF_POWER, CONF_UART_ID, \
|
||||
CONF_VOLTAGE
|
||||
from esphomeyaml.helpers import App, Pvariable, get_variable, setup_component, Component
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
|
||||
CSE7766Component = sensor.sensor_ns.class_('CSE7766Component', Component, uart.UARTDevice)
|
||||
CSE7766VoltageSensor = sensor.sensor_ns.class_('CSE7766VoltageSensor',
|
||||
sensor.EmptySensor)
|
||||
CSE7766CurrentSensor = sensor.sensor_ns.class_('CSE7766CurrentSensor',
|
||||
sensor.EmptySensor)
|
||||
CSE7766PowerSensor = sensor.sensor_ns.class_('CSE7766PowerSensor',
|
||||
sensor.EmptySensor)
|
||||
|
||||
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(CSE7766Component),
|
||||
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
|
||||
|
||||
vol.Optional(CONF_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(CSE7766VoltageSensor),
|
||||
})),
|
||||
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(CSE7766CurrentSensor),
|
||||
})),
|
||||
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(CSE7766PowerSensor),
|
||||
})),
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_VOLTAGE, CONF_CURRENT,
|
||||
CONF_POWER))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for uart_ in get_variable(config[CONF_UART_ID]):
|
||||
yield
|
||||
|
||||
rhs = App.make_cse7766(uart_)
|
||||
cse = Pvariable(config[CONF_ID], rhs)
|
||||
|
||||
if CONF_VOLTAGE in config:
|
||||
conf = config[CONF_VOLTAGE]
|
||||
sensor.register_sensor(cse.make_voltage_sensor(conf[CONF_NAME]), conf)
|
||||
if CONF_CURRENT in config:
|
||||
conf = config[CONF_CURRENT]
|
||||
sensor.register_sensor(cse.make_current_sensor(conf[CONF_NAME]), conf)
|
||||
if CONF_POWER in config:
|
||||
conf = config[CONF_POWER]
|
||||
sensor.register_sensor(cse.make_power_sensor(conf[CONF_NAME]), conf)
|
||||
setup_component(cse, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_CSE7766'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
ret = []
|
||||
for key in (CONF_VOLTAGE, CONF_CURRENT, CONF_POWER):
|
||||
if key in config:
|
||||
ret.append(sensor.core_to_hass_config(data, config[key]))
|
||||
return ret
|
@@ -7,7 +7,11 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAM
|
||||
CONF_RESOLUTION
|
||||
from esphomeyaml.helpers import HexIntLiteral, get_variable
|
||||
|
||||
DallasTemperatureSensor = sensor.sensor_ns.class_('DallasTemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(DallasTemperatureSensor),
|
||||
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
|
||||
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
|
||||
cv.GenerateID(CONF_DALLAS_ID): cv.use_variable_id(DallasComponent),
|
||||
@@ -16,7 +20,6 @@ PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = None
|
||||
for hub in get_variable(config[CONF_DALLAS_ID]):
|
||||
yield
|
||||
if CONF_ADDRESS in config:
|
||||
@@ -29,3 +32,7 @@ def to_code(config):
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return sensor.core_to_hass_config(data, config)
|
||||
|
@@ -3,46 +3,66 @@ import voluptuous as vol
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_MODEL, CONF_NAME, CONF_PIN, \
|
||||
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, add, gpio_output_pin_expression, variable
|
||||
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL, CONF_ID
|
||||
from esphomeyaml.helpers import App, Application, add, gpio_output_pin_expression, variable, \
|
||||
setup_component, PollingComponent, Pvariable
|
||||
from esphomeyaml.pins import gpio_output_pin_schema
|
||||
|
||||
DHTModel = sensor.sensor_ns.enum('DHTModel')
|
||||
DHT_MODELS = {
|
||||
'AUTO_DETECT': sensor.sensor_ns.DHT_MODEL_AUTO_DETECT,
|
||||
'DHT11': sensor.sensor_ns.DHT_MODEL_DHT11,
|
||||
'DHT22': sensor.sensor_ns.DHT_MODEL_DHT22,
|
||||
'AM2302': sensor.sensor_ns.DHT_MODEL_AM2302,
|
||||
'RHT03': sensor.sensor_ns.DHT_MODEL_RHT03,
|
||||
'AUTO_DETECT': DHTModel.DHT_MODEL_AUTO_DETECT,
|
||||
'DHT11': DHTModel.DHT_MODEL_DHT11,
|
||||
'DHT22': DHTModel.DHT_MODEL_DHT22,
|
||||
'AM2302': DHTModel.DHT_MODEL_AM2302,
|
||||
'RHT03': DHTModel.DHT_MODEL_RHT03,
|
||||
}
|
||||
|
||||
MakeDHTSensor = Application.MakeDHTSensor
|
||||
MakeDHTSensor = Application.struct('MakeDHTSensor')
|
||||
DHTComponent = sensor.sensor_ns.class_('DHTComponent', PollingComponent)
|
||||
DHTTemperatureSensor = sensor.sensor_ns.class_('DHTTemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
DHTHumiditySensor = sensor.sensor_ns.class_('DHTHumiditySensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeDHTSensor),
|
||||
cv.GenerateID(): cv.declare_variable_id(DHTComponent),
|
||||
vol.Required(CONF_PIN): gpio_output_pin_schema,
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(DHTTemperatureSensor),
|
||||
})),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(DHTHumiditySensor),
|
||||
})),
|
||||
vol.Optional(CONF_MODEL): vol.All(vol.Upper, cv.one_of(*DHT_MODELS)),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
pin = None
|
||||
for pin in gpio_output_pin_expression(config[CONF_PIN]):
|
||||
yield
|
||||
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_HUMIDITY][CONF_NAME],
|
||||
pin, config.get(CONF_UPDATE_INTERVAL))
|
||||
dht = variable(config[CONF_MAKE_ID], rhs)
|
||||
make = variable(config[CONF_MAKE_ID], rhs)
|
||||
dht = make.Pdht
|
||||
Pvariable(config[CONF_ID], dht)
|
||||
|
||||
if CONF_MODEL in config:
|
||||
constant = DHT_MODELS[config[CONF_MODEL]]
|
||||
add(dht.Pdht.set_dht_model(constant))
|
||||
add(dht.set_dht_model(constant))
|
||||
|
||||
sensor.setup_sensor(dht.Pdht.Pget_temperature_sensor(),
|
||||
dht.Pmqtt_temperature, config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(dht.Pdht.Pget_humidity_sensor(),
|
||||
dht.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||
sensor.setup_sensor(dht.Pget_temperature_sensor(),
|
||||
make.Pmqtt_temperature, config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(dht.Pget_humidity_sensor(),
|
||||
make.Pmqtt_humidity, config[CONF_HUMIDITY])
|
||||
setup_component(dht, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_DHT_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
|
||||
|
@@ -1,33 +1,52 @@
|
||||
import voluptuous as vol
|
||||
|
||||
import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.components import sensor, i2c
|
||||
from esphomeyaml.const import CONF_HUMIDITY, CONF_MAKE_ID, CONF_NAME, CONF_TEMPERATURE, \
|
||||
CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, variable
|
||||
CONF_UPDATE_INTERVAL, CONF_ID
|
||||
from esphomeyaml.helpers import App, Application, variable, setup_component, PollingComponent, \
|
||||
Pvariable
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
MakeDHT12Sensor = Application.MakeDHT12Sensor
|
||||
MakeDHT12Sensor = Application.struct('MakeDHT12Sensor')
|
||||
DHT12Component = sensor.sensor_ns.class_('DHT12Component', PollingComponent, i2c.I2CDevice)
|
||||
DHT12TemperatureSensor = sensor.sensor_ns.class_('DHT12TemperatureSensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
DHT12HumiditySensor = sensor.sensor_ns.class_('DHT12HumiditySensor',
|
||||
sensor.EmptyPollingParentSensor)
|
||||
|
||||
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeDHT12Sensor),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA),
|
||||
cv.GenerateID(): cv.declare_variable_id(DHT12Component),
|
||||
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(DHT12TemperatureSensor),
|
||||
})),
|
||||
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(DHT12HumiditySensor),
|
||||
})),
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
})
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
rhs = App.make_dht12_sensor(config[CONF_TEMPERATURE][CONF_NAME],
|
||||
config[CONF_HUMIDITY][CONF_NAME],
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
dht = variable(config[CONF_MAKE_ID], rhs)
|
||||
make = variable(config[CONF_MAKE_ID], rhs)
|
||||
dht = make.Pdht12
|
||||
Pvariable(config[CONF_ID], dht)
|
||||
|
||||
sensor.setup_sensor(dht.Pdht12.Pget_temperature_sensor(), dht.Pmqtt_temperature,
|
||||
sensor.setup_sensor(dht.Pget_temperature_sensor(), make.Pmqtt_temperature,
|
||||
config[CONF_TEMPERATURE])
|
||||
sensor.setup_sensor(dht.Pdht12.Pget_humidity_sensor(), dht.Pmqtt_humidity,
|
||||
sensor.setup_sensor(dht.Pget_humidity_sensor(), make.Pmqtt_humidity,
|
||||
config[CONF_HUMIDITY])
|
||||
setup_component(dht, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_DHT12_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return [sensor.core_to_hass_config(data, config[CONF_TEMPERATURE]),
|
||||
sensor.core_to_hass_config(data, config[CONF_HUMIDITY])]
|
||||
|
@@ -4,25 +4,32 @@ import esphomeyaml.config_validation as cv
|
||||
from esphomeyaml import pins
|
||||
from esphomeyaml.components import sensor
|
||||
from esphomeyaml.const import CONF_MAKE_ID, CONF_NAME, CONF_PIN, CONF_UPDATE_INTERVAL
|
||||
from esphomeyaml.helpers import App, Application, gpio_input_pin_expression, variable
|
||||
from esphomeyaml.helpers import App, Application, gpio_input_pin_expression, variable, \
|
||||
setup_component
|
||||
|
||||
MakeDutyCycleSensor = Application.MakeDutyCycleSensor
|
||||
MakeDutyCycleSensor = Application.struct('MakeDutyCycleSensor')
|
||||
DutyCycleSensor = sensor.sensor_ns.class_('DutyCycleSensor', sensor.PollingSensorComponent)
|
||||
|
||||
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_variable_id(DutyCycleSensor),
|
||||
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeDutyCycleSensor),
|
||||
vol.Required(CONF_PIN): pins.internal_gpio_input_pin_schema,
|
||||
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
|
||||
}))
|
||||
}).extend(cv.COMPONENT_SCHEMA.schema))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
pin = None
|
||||
for pin in gpio_input_pin_expression(config[CONF_PIN]):
|
||||
yield
|
||||
rhs = App.make_duty_cycle_sensor(config[CONF_NAME], pin,
|
||||
config.get(CONF_UPDATE_INTERVAL))
|
||||
make = variable(config[CONF_MAKE_ID], rhs)
|
||||
sensor.setup_sensor(make.Pduty, make.Pmqtt, config)
|
||||
setup_component(make.Pduty, config)
|
||||
|
||||
|
||||
BUILD_FLAGS = '-DUSE_DUTY_CYCLE_SENSOR'
|
||||
|
||||
|
||||
def to_hass_config(data, config):
|
||||
return sensor.core_to_hass_config(data, config)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user