mirror of
https://github.com/esphome/esphome.git
synced 2025-08-11 04:39:30 +00:00
Compare commits
408 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
390766eb67 | ||
![]() |
899d280ac7 | ||
![]() |
96dc7f0259 | ||
![]() |
0104bf3fc8 | ||
![]() |
9b1e1bf56c | ||
![]() |
33e0f16b3b | ||
![]() |
0807d60c6a | ||
![]() |
f018fde369 | ||
![]() |
c47f8fc02c | ||
![]() |
76ab923780 | ||
![]() |
11dba3147d | ||
![]() |
8c2d9101d5 | ||
![]() |
61b8004536 | ||
![]() |
db02c4ea21 | ||
![]() |
f077a5962d | ||
![]() |
fa4ba43eb9 | ||
![]() |
9579423b24 | ||
![]() |
02449f24c9 | ||
![]() |
b973238323 | ||
![]() |
582b8383d2 | ||
![]() |
e1c9418aee | ||
![]() |
2aa787f5f0 | ||
![]() |
2189a40a39 | ||
![]() |
51688d4078 | ||
![]() |
cc4c0e3e0b | ||
![]() |
1a44c6487e | ||
![]() |
5e7ce610a0 | ||
![]() |
1f02096edb | ||
![]() |
fd7d3c4332 | ||
![]() |
61cf566560 | ||
![]() |
97d624114d | ||
![]() |
52e8a2e9e4 | ||
![]() |
261c271d60 | ||
![]() |
cb6e314336 | ||
![]() |
90315b3c40 | ||
![]() |
5d7c3d1622 | ||
![]() |
8c1ad1e9a6 | ||
![]() |
969f6dbe13 | ||
![]() |
6cce6d4c36 | ||
![]() |
d27e5e9c97 | ||
![]() |
af3b22f8b7 | ||
![]() |
cbc1b29f3e | ||
![]() |
f4ce8b8b6c | ||
![]() |
54363f1246 | ||
![]() |
11727391ad | ||
![]() |
d500531c04 | ||
![]() |
689dcd1e24 | ||
![]() |
2fc4e88271 | ||
![]() |
853d81c6dd | ||
![]() |
e35de626a4 | ||
![]() |
41f29c46d0 | ||
![]() |
9d95f5c1da | ||
![]() |
5d5cc96017 | ||
![]() |
c9a8911029 | ||
![]() |
c77a9ad363 | ||
![]() |
511af5845e | ||
![]() |
6b96089f02 | ||
![]() |
46be886ca6 | ||
![]() |
be7e167c63 | ||
![]() |
c65d78f568 | ||
![]() |
412a866de8 | ||
![]() |
e09c217fde | ||
![]() |
af62c2d9cf | ||
![]() |
aba3cd557a | ||
![]() |
7e7c83b3ca | ||
![]() |
ee4ccf2762 | ||
![]() |
fa0dcac2c7 | ||
![]() |
44e5b0c745 | ||
![]() |
b6d5cb4142 | ||
![]() |
4e8cba49f1 | ||
![]() |
506c2ba6c7 | ||
![]() |
050fa0d4c1 | ||
![]() |
88bb051f37 | ||
![]() |
0d800958aa | ||
![]() |
471533d041 | ||
![]() |
7dfc4c74da | ||
![]() |
f709350b04 | ||
![]() |
85c5928baa | ||
![]() |
f5dfbaff4b | ||
![]() |
689c2f11a3 | ||
![]() |
f73fd97525 | ||
![]() |
f38849828d | ||
![]() |
e95ba57a61 | ||
![]() |
4913256597 | ||
![]() |
401a386219 | ||
![]() |
205f41509b | ||
![]() |
e87c8d550b | ||
![]() |
a33b8abce8 | ||
![]() |
40523e6823 | ||
![]() |
5e1472185c | ||
![]() |
af005a6554 | ||
![]() |
efd31be21c | ||
![]() |
e9bda2810f | ||
![]() |
ec4777b8d0 | ||
![]() |
589b9e10b2 | ||
![]() |
2513ede3ec | ||
![]() |
0b5a57ead4 | ||
![]() |
b3dc2d43a5 | ||
![]() |
d3913be7e5 | ||
![]() |
2c94c3d96f | ||
![]() |
4d81153150 | ||
![]() |
507dc5f496 | ||
![]() |
4335543575 | ||
![]() |
9b75121337 | ||
![]() |
d262548d2e | ||
![]() |
b5b654e054 | ||
![]() |
dae8ab563c | ||
![]() |
12365976c4 | ||
![]() |
4ac4492241 | ||
![]() |
57b7dd0fa2 | ||
![]() |
9d4f471855 | ||
![]() |
5751e9ec59 | ||
![]() |
cc1b7a7a56 | ||
![]() |
29249cdc1b | ||
![]() |
e5bae8187f | ||
![]() |
69adebfefa | ||
![]() |
7dabbb65d0 | ||
![]() |
b30bab8c1b | ||
![]() |
5360e14a9c | ||
![]() |
86db559f6e | ||
![]() |
2f7a378c7b | ||
![]() |
607d0b4264 | ||
![]() |
0a1ed58454 | ||
![]() |
5f5ee9c920 | ||
![]() |
0aeebdd289 | ||
![]() |
33e2aa341e | ||
![]() |
a42788812e | ||
![]() |
b07a038bc8 | ||
![]() |
17e1d4c245 | ||
![]() |
a031cc3b84 | ||
![]() |
c34d5111fc | ||
![]() |
727056a28c | ||
![]() |
0ca8dcd08e | ||
![]() |
3c7c4e1dba | ||
![]() |
518ecb4cc4 | ||
![]() |
55e36ab982 | ||
![]() |
90835ab917 | ||
![]() |
5b46088ae4 | ||
![]() |
d7e267eca5 | ||
![]() |
807c47a076 | ||
![]() |
7ebe6a5894 | ||
![]() |
41c829fa32 | ||
![]() |
8f1ce8c7f7 | ||
![]() |
e55636ed52 | ||
![]() |
e886262055 | ||
![]() |
2fa7f8c511 | ||
![]() |
4622ef770d | ||
![]() |
d76f18b4f2 | ||
![]() |
ec20778d83 | ||
![]() |
b3ca71c6fb | ||
![]() |
1100f67b66 | ||
![]() |
056a28906b | ||
![]() |
2c2821cd96 | ||
![]() |
157a3e53dd | ||
![]() |
61edf8c196 | ||
![]() |
397f57ce74 | ||
![]() |
bf253c21fa | ||
![]() |
e3eef1cc6d | ||
![]() |
11f6e555f9 | ||
![]() |
164631fcec | ||
![]() |
a61e3fadf6 | ||
![]() |
b5f2d69ca5 | ||
![]() |
55b5c0fc32 | ||
![]() |
280b090dfc | ||
![]() |
2d53dd05d8 | ||
![]() |
9d97807587 | ||
![]() |
11433c8c17 | ||
![]() |
68a2c45edf | ||
![]() |
d2616cd6c6 | ||
![]() |
736dbfac13 | ||
![]() |
b8fa737bc9 | ||
![]() |
bf5352b44e | ||
![]() |
bff74af882 | ||
![]() |
dadbc1aefa | ||
![]() |
fc354eec0e | ||
![]() |
47b1b45828 | ||
![]() |
e6da2313e6 | ||
![]() |
fe81bcc003 | ||
![]() |
10eee47b6b | ||
![]() |
c930c86cfa | ||
![]() |
d3196e0e34 | ||
![]() |
deb34c9473 | ||
![]() |
892d2ce34f | ||
![]() |
b107948c47 | ||
![]() |
d2648657fb | ||
![]() |
32b103eb1d | ||
![]() |
e66047e072 | ||
![]() |
0c84224ca2 | ||
![]() |
7bb67ae94b | ||
![]() |
ccc30116ba | ||
![]() |
9cf115a752 | ||
![]() |
d9523a0cbf | ||
![]() |
2fd6942de4 | ||
![]() |
b19a7e006e | ||
![]() |
5c26f95a4b | ||
![]() |
ce171f5c00 | ||
![]() |
ab872b075a | ||
![]() |
87395d259e | ||
![]() |
72f29b1283 | ||
![]() |
f2a6f18553 | ||
![]() |
8cac5ca90c | ||
![]() |
01ec414873 | ||
![]() |
6b0fb3dd06 | ||
![]() |
e89c6494a6 | ||
![]() |
eff76d578b | ||
![]() |
76ebbfefd2 | ||
![]() |
150c9b5fa3 | ||
![]() |
55df88d7ae | ||
![]() |
619787e6d2 | ||
![]() |
3f8bad3ed1 | ||
![]() |
c146712b16 | ||
![]() |
2cabe59c22 | ||
![]() |
feba9ffdc4 | ||
![]() |
74ab940aff | ||
![]() |
82c1988a2d | ||
![]() |
ac5c6ec288 | ||
![]() |
47735d1dae | ||
![]() |
35b5dadb99 | ||
![]() |
e2d784a5b5 | ||
![]() |
b7a16d5a59 | ||
![]() |
97dcbe84da | ||
![]() |
32b24726ed | ||
![]() |
343278b291 | ||
![]() |
b11824b058 | ||
![]() |
562f7c8718 | ||
![]() |
d382ca2401 | ||
![]() |
a9630ac847 | ||
![]() |
22c0b0abaa | ||
![]() |
aabe0091cc | ||
![]() |
3d9af2a67c | ||
![]() |
4ae582c305 | ||
![]() |
5fdafc00e6 | ||
![]() |
2165960ba1 | ||
![]() |
2bb5f53b98 | ||
![]() |
211b3eddea | ||
![]() |
bec53f97a2 | ||
![]() |
c3332e4a39 | ||
![]() |
f8a03be2f1 | ||
![]() |
712634b301 | ||
![]() |
19d53c6643 | ||
![]() |
f14419bab5 | ||
![]() |
3003485dc6 | ||
![]() |
01f6791d1c | ||
![]() |
cdb67fc90e | ||
![]() |
78cb098691 | ||
![]() |
45152ad55e | ||
![]() |
45879e3100 | ||
![]() |
c4adb30ab2 | ||
![]() |
b20bae23cc | ||
![]() |
11ed2d5f18 | ||
![]() |
f814b6d47c | ||
![]() |
a67b92a04c | ||
![]() |
2a48b810a4 | ||
![]() |
9fb8e9edef | ||
![]() |
d2bccbe8ac | ||
![]() |
e44a60e814 | ||
![]() |
02a71cb6a7 | ||
![]() |
e600784ebf | ||
![]() |
5e19a3b892 | ||
![]() |
0443310385 | ||
![]() |
03ab23fec8 | ||
![]() |
da8afd36b2 | ||
![]() |
fe7893d1b3 | ||
![]() |
d19bf5d6ee | ||
![]() |
bfdcfa4766 | ||
![]() |
c47c1a7867 | ||
![]() |
f16a24ddf4 | ||
![]() |
8bf112669f | ||
![]() |
4278664208 | ||
![]() |
0789657fd5 | ||
![]() |
b566c78f00 | ||
![]() |
c287e529a8 | ||
![]() |
164d05fdce | ||
![]() |
c11c4dad2f | ||
![]() |
0af8d0b7ea | ||
![]() |
2b4ed0c273 | ||
![]() |
9fc50e8dbc | ||
![]() |
a35122231c | ||
![]() |
7e4ee32b54 | ||
![]() |
7df80eadcf | ||
![]() |
2aaba1d2b8 | ||
![]() |
7c129a4018 | ||
![]() |
cb66ce069e | ||
![]() |
a27e72362a | ||
![]() |
c5be5e6d12 | ||
![]() |
63fc16d872 | ||
![]() |
5f99ed943a | ||
![]() |
f44e5d3142 | ||
![]() |
532163738e | ||
![]() |
63fa922547 | ||
![]() |
48e4cb5ae2 | ||
![]() |
ff8a73c2d1 | ||
![]() |
afd26c6f1a | ||
![]() |
67b06a88b2 | ||
![]() |
5cb5594288 | ||
![]() |
87629191b3 | ||
![]() |
4a518e3e7a | ||
![]() |
6089526975 | ||
![]() |
b9e9223fdd | ||
![]() |
e963eedb64 | ||
![]() |
3b2c61e813 | ||
![]() |
265e019381 | ||
![]() |
560e36a65c | ||
![]() |
b05a3fbb55 | ||
![]() |
3a899e28dc | ||
![]() |
f26238e824 | ||
![]() |
3717e34bba | ||
![]() |
be6f95d43e | ||
![]() |
99a765dc06 | ||
![]() |
351e7ea16b | ||
![]() |
2fa79a2e2f | ||
![]() |
44a917929d | ||
![]() |
2dd4aa7bf6 | ||
![]() |
4c1af007ca | ||
![]() |
08013be6dd | ||
![]() |
0daf4545a9 | ||
![]() |
1269bf9791 | ||
![]() |
5cb21324a1 | ||
![]() |
3eef80506b | ||
![]() |
283d9a0f5f | ||
![]() |
a84365659b | ||
![]() |
21ebc7f95b | ||
![]() |
72e72d7d4b | ||
![]() |
db9dc11022 | ||
![]() |
02ed2c0ebe | ||
![]() |
0f506ea8eb | ||
![]() |
8e7e8da4a3 | ||
![]() |
b56c606523 | ||
![]() |
f457269a68 | ||
![]() |
5b0b9da0b9 | ||
![]() |
0ed0bdc655 | ||
![]() |
a8fa4b56f9 | ||
![]() |
cd514b140e | ||
![]() |
f3329fdc8c | ||
![]() |
689bbf2419 | ||
![]() |
a6b89e4e8a | ||
![]() |
ffd2cb9814 | ||
![]() |
1d5f088740 | ||
![]() |
4e7011c25d | ||
![]() |
f4ac176d77 | ||
![]() |
e4cf7b86fa | ||
![]() |
9876d5276c | ||
![]() |
0b1b25191d | ||
![]() |
9980b9972f | ||
![]() |
93b7ca77ca | ||
![]() |
40697fea96 | ||
![]() |
c541fa1763 | ||
![]() |
fd08f1e23d | ||
![]() |
3a07121784 | ||
![]() |
1495fada90 | ||
![]() |
62fed4c1eb | ||
![]() |
00f9af70a9 | ||
![]() |
0ae3fcb0b7 | ||
![]() |
dfffa67c0f | ||
![]() |
f81c556b63 | ||
![]() |
ce8091c14e | ||
![]() |
581cb642ff | ||
![]() |
e02aaedc42 | ||
![]() |
8c66de2391 | ||
![]() |
cb8ca433d9 | ||
![]() |
17be6b106b | ||
![]() |
869981cfe4 | ||
![]() |
7dd56fb0fa | ||
![]() |
f0f09d3714 | ||
![]() |
9a66199904 | ||
![]() |
bf732f2a2b | ||
![]() |
c418eecf83 | ||
![]() |
98bf427600 | ||
![]() |
9aa5ee3372 | ||
![]() |
ccb3d3d308 | ||
![]() |
9ff0471274 | ||
![]() |
fdb20e4a30 | ||
![]() |
56630bb717 | ||
![]() |
08a41d9bd6 | ||
![]() |
cd46a69f2c | ||
![]() |
794a4bd9a1 | ||
![]() |
a120a455bf | ||
![]() |
cd72a2ed7e | ||
![]() |
3eff7e76aa | ||
![]() |
959d1944fd | ||
![]() |
b0966532bf | ||
![]() |
827b2def1e | ||
![]() |
80154b280e | ||
![]() |
efd0dd4c3d | ||
![]() |
c91b775b73 | ||
![]() |
1c237aef77 | ||
![]() |
89c5298bb9 | ||
![]() |
76c0d0912f | ||
![]() |
5eb12ac5fe | ||
![]() |
d238155640 | ||
![]() |
de626c0f5f | ||
![]() |
973e78355f | ||
![]() |
b82c7ad608 | ||
![]() |
417d45939f | ||
![]() |
837c749cd7 | ||
![]() |
b0e286972d | ||
![]() |
3cfe1e3083 | ||
![]() |
6738295475 | ||
![]() |
1617eba764 | ||
![]() |
899aa31df3 | ||
![]() |
ac81fae855 | ||
![]() |
8c6cddf1bb | ||
![]() |
508392db6e | ||
![]() |
3ac0165f00 | ||
![]() |
1691c13b47 | ||
![]() |
f8df694aa3 | ||
![]() |
ac05495781 | ||
![]() |
306ab0c56c |
15
.clang-tidy
15
.clang-tidy
@@ -5,9 +5,12 @@ Checks: >-
|
||||
-altera-*,
|
||||
-android-*,
|
||||
-boost-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-signed-char-misuse,
|
||||
-cert-dcl50-cpp,
|
||||
-cert-err33-c,
|
||||
-cert-err58-cpp,
|
||||
-cert-oop57-cpp,
|
||||
-cert-str34-c,
|
||||
@@ -15,6 +18,7 @@ Checks: >-
|
||||
-clang-analyzer-osx.*,
|
||||
-clang-diagnostic-delete-abstract-non-virtual-dtor,
|
||||
-clang-diagnostic-delete-non-abstract-non-virtual-dtor,
|
||||
-clang-diagnostic-ignored-optimization-argument,
|
||||
-clang-diagnostic-shadow-field,
|
||||
-clang-diagnostic-unused-const-variable,
|
||||
-clang-diagnostic-unused-parameter,
|
||||
@@ -25,6 +29,7 @@ Checks: >-
|
||||
-cppcoreguidelines-macro-usage,
|
||||
-cppcoreguidelines-narrowing-conversions,
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
-cppcoreguidelines-prefer-member-initializer,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||
@@ -36,6 +41,7 @@ Checks: >-
|
||||
-cppcoreguidelines-pro-type-union-access,
|
||||
-cppcoreguidelines-pro-type-vararg,
|
||||
-cppcoreguidelines-special-member-functions,
|
||||
-cppcoreguidelines-virtual-class-destructor,
|
||||
-fuchsia-multiple-inheritance,
|
||||
-fuchsia-overloaded-operator,
|
||||
-fuchsia-statically-constructed-objects,
|
||||
@@ -68,6 +74,7 @@ Checks: >-
|
||||
-modernize-use-nodiscard,
|
||||
-mpi-*,
|
||||
-objc-*,
|
||||
-readability-container-data-pointer,
|
||||
-readability-convert-member-functions-to-static,
|
||||
-readability-else-after-return,
|
||||
-readability-function-cognitive-complexity,
|
||||
@@ -82,8 +89,6 @@ WarningsAsErrors: '*'
|
||||
AnalyzeTemporaryDtors: false
|
||||
FormatStyle: google
|
||||
CheckOptions:
|
||||
- key: google-readability-braces-around-statements.ShortStatementLines
|
||||
value: '1'
|
||||
- key: google-readability-function-size.StatementThreshold
|
||||
value: '800'
|
||||
- key: google-runtime-int.TypeSuffix
|
||||
@@ -158,3 +163,9 @@ CheckOptions:
|
||||
value: ''
|
||||
- key: readability-qualified-auto.AddConstToQualified
|
||||
value: 0
|
||||
- key: readability-identifier-length.MinimumVariableNameLength
|
||||
value: 0
|
||||
- key: readability-identifier-length.MinimumParameterNameLength
|
||||
value: 0
|
||||
- key: readability-identifier-length.MinimumLoopCounterNameLength
|
||||
value: 0
|
||||
|
4
.github/actions/restore-python/action.yml
vendored
4
.github/actions/restore-python/action.yml
vendored
@@ -17,12 +17,12 @@ runs:
|
||||
steps:
|
||||
- name: Set up Python ${{ inputs.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.6.0
|
||||
uses: actions/setup-python@v4.7.0
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.3.1
|
||||
uses: actions/cache/restore@v3.3.2
|
||||
with:
|
||||
path: venv
|
||||
# yamllint disable-line rule:line-length
|
||||
|
12
.github/workflows/ci-docker.yml
vendored
12
.github/workflows/ci-docker.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
branches: [dev, beta, release]
|
||||
paths:
|
||||
- "docker/**"
|
||||
- ".github/workflows/**"
|
||||
- ".github/workflows/ci-docker.yml"
|
||||
- "requirements*.txt"
|
||||
- "platformio.ini"
|
||||
- "script/platformio_install_deps.py"
|
||||
@@ -16,7 +16,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "docker/**"
|
||||
- ".github/workflows/**"
|
||||
- ".github/workflows/ci-docker.yml"
|
||||
- "requirements*.txt"
|
||||
- "platformio.ini"
|
||||
- "script/platformio_install_deps.py"
|
||||
@@ -40,15 +40,15 @@ jobs:
|
||||
arch: [amd64, armv7, aarch64]
|
||||
build_type: ["ha-addon", "docker", "lint"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4.1.0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v4.7.1
|
||||
with:
|
||||
python-version: "3.9"
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3.0.0
|
||||
|
||||
- name: Set TAG
|
||||
run: |
|
||||
|
62
.github/workflows/ci.yml
vendored
62
.github/workflows/ci.yml
vendored
@@ -7,6 +7,10 @@ on:
|
||||
branches: [dev, beta, release]
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- "**"
|
||||
- "!.github/workflows/*.yml"
|
||||
- ".github/workflows/ci.yml"
|
||||
merge_group:
|
||||
|
||||
permissions:
|
||||
@@ -30,18 +34,18 @@ jobs:
|
||||
cache-key: ${{ steps.cache-key.outputs.key }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Generate cache-key
|
||||
id: cache-key
|
||||
run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.6.0
|
||||
uses: actions/setup-python@v4.7.1
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v3.3.1
|
||||
uses: actions/cache@v3.3.2
|
||||
with:
|
||||
path: venv
|
||||
# yamllint disable-line rule:line-length
|
||||
@@ -55,15 +59,6 @@ jobs:
|
||||
pip install -r requirements.txt -r requirements_optional.txt -r requirements_test.txt
|
||||
pip install -e .
|
||||
|
||||
yamllint:
|
||||
name: yamllint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
- name: Run yamllint
|
||||
uses: frenck/action-yamllint@v1.4.1
|
||||
|
||||
black:
|
||||
name: Check black
|
||||
runs-on: ubuntu-latest
|
||||
@@ -71,7 +66,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -92,7 +87,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -113,7 +108,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -134,7 +129,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -155,7 +150,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -176,7 +171,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -196,7 +191,7 @@ jobs:
|
||||
- common
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
@@ -215,6 +210,17 @@ jobs:
|
||||
run: script/ci-suggest-changes
|
||||
if: always()
|
||||
|
||||
compile-tests-list:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Find all YAML test files
|
||||
id: set-matrix
|
||||
run: echo "matrix=$(ls tests/test*.yaml | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT
|
||||
|
||||
compile-tests:
|
||||
name: Run YAML test ${{ matrix.file }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -227,24 +233,24 @@ jobs:
|
||||
- pylint
|
||||
- pytest
|
||||
- pyupgrade
|
||||
- yamllint
|
||||
- compile-tests-list
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 2
|
||||
matrix:
|
||||
file: [1, 2, 3, 3.1, 4, 5, 6, 7, 8]
|
||||
file: ${{ fromJson(needs.compile-tests-list.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
- name: Run esphome compile tests/test${{ matrix.file }}.yaml
|
||||
- name: Run esphome compile ${{ matrix.file }}
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
esphome compile tests/test${{ matrix.file }}.yaml
|
||||
esphome compile ${{ matrix.file }}
|
||||
|
||||
clang-tidy:
|
||||
name: ${{ matrix.name }}
|
||||
@@ -258,7 +264,6 @@ jobs:
|
||||
- pylint
|
||||
- pytest
|
||||
- pyupgrade
|
||||
- yamllint
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 2
|
||||
@@ -291,21 +296,21 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.5.2
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Restore Python
|
||||
uses: ./.github/actions/restore-python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
- name: Cache platformio
|
||||
uses: actions/cache@v3.3.1
|
||||
uses: actions/cache@v3.3.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
# yamllint disable-line rule:line-length
|
||||
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
- name: Install clang-tidy
|
||||
run: sudo apt-get install clang-tidy-11
|
||||
run: sudo apt-get install clang-tidy-14
|
||||
|
||||
- name: Register problem matchers
|
||||
run: |
|
||||
@@ -337,7 +342,6 @@ jobs:
|
||||
- pylint
|
||||
- pytest
|
||||
- pyupgrade
|
||||
- yamllint
|
||||
- compile-tests
|
||||
- clang-tidy
|
||||
if: always()
|
||||
|
2
.github/workflows/lock.yml
vendored
2
.github/workflows/lock.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v4
|
||||
- uses: dessant/lock-threads@v4.0.1
|
||||
with:
|
||||
pr-inactive-days: "1"
|
||||
pr-lock-reason: ""
|
||||
|
22
.github/workflows/release.yml
vendored
22
.github/workflows/release.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
outputs:
|
||||
tag: ${{ steps.tag.outputs.tag }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4.1.0
|
||||
- name: Get tag
|
||||
id: tag
|
||||
# yamllint disable rule:line-length
|
||||
@@ -43,9 +43,9 @@ jobs:
|
||||
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4.1.0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v4.7.1
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Set up python environment
|
||||
@@ -88,24 +88,24 @@ jobs:
|
||||
target: "lint"
|
||||
baseimg: "docker"
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4.1.0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v4.7.1
|
||||
with:
|
||||
python-version: "3.9"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3.0.0
|
||||
|
||||
- name: Log in to docker hub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Log in to the GitHub container registry
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -119,7 +119,7 @@ jobs:
|
||||
--suffix "${{ matrix.image.suffix }}"
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5.0.0
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
needs: [deploy-docker]
|
||||
steps:
|
||||
- name: Trigger Workflow
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v6.4.1
|
||||
with:
|
||||
github-token: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
|
||||
script: |
|
||||
|
4
.github/workflows/stale.yml
vendored
4
.github/workflows/stale.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
- uses: actions/stale@v8.0.0
|
||||
with:
|
||||
days-before-pr-stale: 90
|
||||
days-before-pr-close: 7
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
- uses: actions/stale@v8.0.0
|
||||
with:
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
|
11
.github/workflows/sync-device-classes.yml
vendored
11
.github/workflows/sync-device-classes.yml
vendored
@@ -4,8 +4,7 @@ name: Synchronise Device Classes from Home Assistant
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '45 6 * * *'
|
||||
|
||||
- cron: "45 6 * * *"
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
@@ -14,16 +13,16 @@ jobs:
|
||||
if: github.repository == 'esphome/esphome'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4.1.0
|
||||
|
||||
- name: Checkout Home Assistant
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4.1.0
|
||||
with:
|
||||
repository: home-assistant/core
|
||||
path: lib/home-assistant
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v4.7.1
|
||||
with:
|
||||
python-version: 3.11
|
||||
|
||||
@@ -37,7 +36,7 @@ jobs:
|
||||
python ./script/sync-device_class.py
|
||||
|
||||
- name: Commit changes
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
uses: peter-evans/create-pull-request@v5.0.2
|
||||
with:
|
||||
commit-message: "Synchronise Device Classes from Home Assistant"
|
||||
committer: esphomebot <esphome@nabucasa.com>
|
||||
|
22
.github/workflows/yaml-lint.yml
vendored
Normal file
22
.github/workflows/yaml-lint.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: YAML lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [dev, beta, release]
|
||||
paths:
|
||||
- "**.yaml"
|
||||
- "**.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.yaml"
|
||||
- "**.yml"
|
||||
|
||||
jobs:
|
||||
yamllint:
|
||||
name: yamllint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4.1.0
|
||||
- name: Run yamllint
|
||||
uses: frenck/action-yamllint@v1.4.1
|
10
.gitignore
vendored
10
.gitignore
vendored
@@ -13,6 +13,12 @@ __pycache__/
|
||||
# Intellij Idea
|
||||
.idea
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.cproject
|
||||
.pydevproject
|
||||
.settings/
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
|
||||
@@ -129,4 +135,6 @@ tests/.esphome/
|
||||
sdkconfig.*
|
||||
!sdkconfig.defaults
|
||||
|
||||
.tests/
|
||||
.tests/
|
||||
|
||||
/components
|
||||
|
@@ -2,8 +2,8 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.3.0
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 23.9.1
|
||||
hooks:
|
||||
- id: black
|
||||
args:
|
||||
@@ -27,7 +27,7 @@ repos:
|
||||
- --branch=release
|
||||
- --branch=beta
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.7.0
|
||||
rev: v3.10.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
|
31
CODEOWNERS
31
CODEOWNERS
@@ -11,6 +11,7 @@ esphome/*.py @esphome/core
|
||||
esphome/core/* @esphome/core
|
||||
|
||||
# Integrations
|
||||
esphome/components/a01nyub/* @MrSuicideParrot
|
||||
esphome/components/absolute_humidity/* @DAVe3283
|
||||
esphome/components/ac_dimmer/* @glmnet
|
||||
esphome/components/adc/* @esphome/core
|
||||
@@ -41,18 +42,21 @@ esphome/components/bedjet/climate/* @jhansche
|
||||
esphome/components/bedjet/fan/* @jhansche
|
||||
esphome/components/bh1750/* @OttoWinter
|
||||
esphome/components/binary_sensor/* @esphome/core
|
||||
esphome/components/bk72xx/* @kuba2k2
|
||||
esphome/components/bl0939/* @ziceva
|
||||
esphome/components/bl0940/* @tobias-
|
||||
esphome/components/bl0942/* @dbuezas
|
||||
esphome/components/ble_client/* @buxtronix
|
||||
esphome/components/bluetooth_proxy/* @jesserockz
|
||||
esphome/components/bme680_bsec/* @trvrnrth
|
||||
esphome/components/bmi160/* @flaviut
|
||||
esphome/components/bmp3xx/* @martgras
|
||||
esphome/components/bmp581/* @kahrendt
|
||||
esphome/components/bp1658cj/* @Cossid
|
||||
esphome/components/bp5758d/* @Cossid
|
||||
esphome/components/button/* @esphome/core
|
||||
esphome/components/canbus/* @danielschramm @mvturnho
|
||||
esphome/components/cap1188/* @MrEditor97
|
||||
esphome/components/cap1188/* @mreditor97
|
||||
esphome/components/captive_portal/* @OttoWinter
|
||||
esphome/components/ccs811/* @habbie
|
||||
esphome/components/cd74hc4067/* @asoehlke
|
||||
@@ -85,7 +89,7 @@ esphome/components/ens210/* @itn3rd77
|
||||
esphome/components/esp32/* @esphome/core
|
||||
esphome/components/esp32_ble/* @jesserockz
|
||||
esphome/components/esp32_ble_client/* @jesserockz
|
||||
esphome/components/esp32_ble_server/* @jesserockz
|
||||
esphome/components/esp32_ble_server/* @clydebarrow @jesserockz
|
||||
esphome/components/esp32_camera_web_server/* @ayufan
|
||||
esphome/components/esp32_can/* @Sympatron
|
||||
esphome/components/esp32_improv/* @jesserockz
|
||||
@@ -100,6 +104,7 @@ esphome/components/fastled_base/* @OttoWinter
|
||||
esphome/components/feedback/* @ianchi
|
||||
esphome/components/fingerprint_grow/* @OnFreund @loongyh
|
||||
esphome/components/fs3000/* @kahrendt
|
||||
esphome/components/gcja5/* @gcormier
|
||||
esphome/components/globals/* @esphome/core
|
||||
esphome/components/gp8403/* @jesserockz
|
||||
esphome/components/gpio/* @esphome/core
|
||||
@@ -126,10 +131,10 @@ esphome/components/i2s_audio/* @jesserockz
|
||||
esphome/components/i2s_audio/media_player/* @jesserockz
|
||||
esphome/components/i2s_audio/microphone/* @jesserockz
|
||||
esphome/components/i2s_audio/speaker/* @jesserockz
|
||||
esphome/components/ili9xxx/* @nielsnl68
|
||||
esphome/components/ili9xxx/* @clydebarrow @nielsnl68
|
||||
esphome/components/improv_base/* @esphome/core
|
||||
esphome/components/improv_serial/* @esphome/core
|
||||
esphome/components/ina260/* @MrEditor97
|
||||
esphome/components/ina260/* @mreditor97
|
||||
esphome/components/inkbird_ibsth1_mini/* @fkirill
|
||||
esphome/components/inkplate6/* @jesserockz
|
||||
esphome/components/integration/* @OttoWinter
|
||||
@@ -141,9 +146,12 @@ esphome/components/key_collector/* @ssieb
|
||||
esphome/components/key_provider/* @ssieb
|
||||
esphome/components/kuntze/* @ssieb
|
||||
esphome/components/lcd_menu/* @numo68
|
||||
esphome/components/ld2410/* @sebcaps
|
||||
esphome/components/ld2410/* @regevbr @sebcaps
|
||||
esphome/components/ledc/* @OttoWinter
|
||||
esphome/components/libretiny/* @kuba2k2
|
||||
esphome/components/libretiny_pwm/* @kuba2k2
|
||||
esphome/components/light/* @esphome/core
|
||||
esphome/components/lightwaverf/* @max246
|
||||
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
|
||||
esphome/components/lock/* @esphome/core
|
||||
esphome/components/logger/* @esphome/core
|
||||
@@ -165,7 +173,7 @@ esphome/components/mcp2515/* @danielschramm @mvturnho
|
||||
esphome/components/mcp3204/* @rsumner
|
||||
esphome/components/mcp4728/* @berfenger
|
||||
esphome/components/mcp47a1/* @jesserockz
|
||||
esphome/components/mcp9600/* @MrEditor97
|
||||
esphome/components/mcp9600/* @mreditor97
|
||||
esphome/components/mcp9808/* @k7hpn
|
||||
esphome/components/md5/* @esphome/core
|
||||
esphome/components/mdns/* @esphome/core
|
||||
@@ -178,6 +186,7 @@ esphome/components/mitsubishi/* @RubyBailey
|
||||
esphome/components/mlx90393/* @functionpointer
|
||||
esphome/components/mlx90614/* @jesserockz
|
||||
esphome/components/mmc5603/* @benhoff
|
||||
esphome/components/mmc5983/* @agoode
|
||||
esphome/components/modbus_controller/* @martgras
|
||||
esphome/components/modbus_controller/binary_sensor/* @martgras
|
||||
esphome/components/modbus_controller/number/* @martgras
|
||||
@@ -209,13 +218,14 @@ esphome/components/pid/* @OttoWinter
|
||||
esphome/components/pipsolar/* @andreashergert1984
|
||||
esphome/components/pm1006/* @habbie
|
||||
esphome/components/pmsa003i/* @sjtrny
|
||||
esphome/components/pmwcs3/* @SeByDocKy
|
||||
esphome/components/pn532/* @OttoWinter @jesserockz
|
||||
esphome/components/pn532_i2c/* @OttoWinter @jesserockz
|
||||
esphome/components/pn532_spi/* @OttoWinter @jesserockz
|
||||
esphome/components/power_supply/* @esphome/core
|
||||
esphome/components/preferences/* @esphome/core
|
||||
esphome/components/psram/* @esphome/core
|
||||
esphome/components/pulse_meter/* @cstaahl @stevebaxter
|
||||
esphome/components/pulse_meter/* @TrentHouliston @cstaahl @stevebaxter
|
||||
esphome/components/pvvx_mithermometer/* @pasiz
|
||||
esphome/components/qmp6988/* @andrewpc
|
||||
esphome/components/qr_code/* @wjtje
|
||||
@@ -230,6 +240,7 @@ esphome/components/rgbct/* @jesserockz
|
||||
esphome/components/rp2040/* @jesserockz
|
||||
esphome/components/rp2040_pio_led_strip/* @Papa-DMan
|
||||
esphome/components/rp2040_pwm/* @jesserockz
|
||||
esphome/components/rtl87xx/* @kuba2k2
|
||||
esphome/components/rtttl/* @glmnet
|
||||
esphome/components/safe_mode/* @jsuanet @paulmonigatti
|
||||
esphome/components/scd4x/* @martgras @sjtrny
|
||||
@@ -238,6 +249,7 @@ esphome/components/sdm_meter/* @jesserockz @polyfaces
|
||||
esphome/components/sdp3x/* @Azimath
|
||||
esphome/components/selec_meter/* @sourabhjaiswal
|
||||
esphome/components/select/* @esphome/core
|
||||
esphome/components/sen0321/* @notjj
|
||||
esphome/components/sen21231/* @shreyaskarnik
|
||||
esphome/components/sen5x/* @martgras
|
||||
esphome/components/sensirion_common/* @martgras
|
||||
@@ -259,7 +271,9 @@ esphome/components/sn74hc165/* @jesserockz
|
||||
esphome/components/socket/* @esphome/core
|
||||
esphome/components/sonoff_d1/* @anatoly-savchenkov
|
||||
esphome/components/speaker/* @jesserockz
|
||||
esphome/components/spi/* @esphome/core
|
||||
esphome/components/spi/* @clydebarrow @esphome/core
|
||||
esphome/components/spi_device/* @clydebarrow
|
||||
esphome/components/spi_led_strip/* @clydebarrow
|
||||
esphome/components/sprinkler/* @kbx81
|
||||
esphome/components/sps30/* @martgras
|
||||
esphome/components/ssd1322_base/* @kbx81
|
||||
@@ -320,6 +334,7 @@ esphome/components/web_server_idf/* @dentra
|
||||
esphome/components/whirlpool/* @glmnet
|
||||
esphome/components/whynter/* @aeonsablaze
|
||||
esphome/components/wiegand/* @ssieb
|
||||
esphome/components/wireguard/* @droscy @lhoracek @thomas0bernard
|
||||
esphome/components/wl_134/* @hobbypunk90
|
||||
esphome/components/x9c/* @EtienneMD
|
||||
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
|
||||
|
@@ -22,16 +22,24 @@ RUN \
|
||||
python3=3.9.2-3 \
|
||||
python3-pip=20.3.4-4+deb11u1 \
|
||||
python3-setuptools=52.0.0-4 \
|
||||
python3-pil=8.1.2+dfsg-0.3+deb11u1 \
|
||||
python3-cryptography=3.3.2-1 \
|
||||
python3-venv=3.9.2-3 \
|
||||
iputils-ping=3:20210202-1 \
|
||||
git=1:2.30.2-1+deb11u2 \
|
||||
curl=7.74.0-1.3+deb11u7 \
|
||||
openssh-client=1:8.4p1-5+deb11u1 \
|
||||
libcairo2=1.16.0-5 \
|
||||
curl=7.74.0-1.3+deb11u10 \
|
||||
openssh-client=1:8.4p1-5+deb11u2 \
|
||||
python3-cffi=1.14.5-1 \
|
||||
&& rm -rf \
|
||||
libcairo2=1.16.0-5 \
|
||||
patch=2.7.6-7; \
|
||||
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential=12.9 \
|
||||
python3-dev=3.9.2-3 \
|
||||
zlib1g-dev=1:1.2.11.dfsg-2+deb11u2 \
|
||||
libjpeg-dev=1:2.0.6-4 \
|
||||
libfreetype-dev=2.10.4+dfsg-1+deb11u1; \
|
||||
fi; \
|
||||
rm -rf \
|
||||
/tmp/* \
|
||||
/var/{cache,log}/* \
|
||||
/var/lib/apt/lists/*
|
||||
@@ -54,7 +62,7 @@ RUN \
|
||||
# Ubuntu python3-pip is missing wheel
|
||||
pip3 install --no-cache-dir \
|
||||
wheel==0.37.1 \
|
||||
platformio==6.1.7 \
|
||||
platformio==6.1.11 \
|
||||
# Change some platformio settings
|
||||
&& platformio settings set enable_telemetry No \
|
||||
&& platformio settings set check_platformio_interval 1000000 \
|
||||
|
@@ -35,11 +35,23 @@ if bashio::config.has_value 'default_compile_process_limit'; then
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=$(bashio::config 'default_compile_process_limit')
|
||||
else
|
||||
if grep -q 'Raspberry Pi 3' /proc/cpuinfo; then
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=1;
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=1
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "${pio_cache_base}"
|
||||
|
||||
mkdir -p /config/esphome
|
||||
|
||||
if bashio::fs.directory_exists '/config/esphome/.esphome'; then
|
||||
bashio::log.info "Migrating old .esphome directory..."
|
||||
if bashio::fs.file_exists '/config/esphome/.esphome/esphome.json'; then
|
||||
mv /config/esphome/.esphome/esphome.json /data/esphome.json
|
||||
fi
|
||||
mkdir -p "/data/storage"
|
||||
mv /config/esphome/.esphome/*.json /data/storage/ || true
|
||||
rm -rf /config/esphome/.esphome
|
||||
fi
|
||||
|
||||
bashio::log.info "Starting ESPHome dashboard..."
|
||||
exec esphome dashboard /config/esphome --socket /var/run/esphome.sock --ha-addon
|
||||
|
@@ -26,6 +26,8 @@ from esphome.const import (
|
||||
CONF_ESPHOME,
|
||||
CONF_PLATFORMIO_OPTIONS,
|
||||
CONF_SUBSTITUTIONS,
|
||||
PLATFORM_BK72XX,
|
||||
PLATFORM_RTL87XX,
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_RP2040,
|
||||
@@ -83,6 +85,8 @@ def choose_upload_log_host(
|
||||
options = []
|
||||
for port in get_serial_ports():
|
||||
options.append((f"{port.path} ({port.description})", port.path))
|
||||
if default == "SERIAL":
|
||||
return choose_prompt(options, purpose=purpose)
|
||||
if (show_ota and "ota" in CORE.config) or (show_api and "api" in CORE.config):
|
||||
options.append((f"Over The Air ({CORE.address})", CORE.address))
|
||||
if default == "OTA":
|
||||
@@ -216,14 +220,16 @@ def compile_program(args, config):
|
||||
return 0 if idedata is not None else 1
|
||||
|
||||
|
||||
def upload_using_esptool(config, port):
|
||||
def upload_using_esptool(config, port, file):
|
||||
from esphome import platformio_api
|
||||
|
||||
first_baudrate = config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get(
|
||||
"upload_speed", 460800
|
||||
)
|
||||
|
||||
def run_esptool(baud_rate):
|
||||
if file is not None:
|
||||
flash_images = [platformio_api.FlashImage(path=file, offset="0x0")]
|
||||
else:
|
||||
idedata = platformio_api.get_idedata(config)
|
||||
|
||||
firmware_offset = "0x10000" if CORE.is_esp32 else "0x0"
|
||||
@@ -234,12 +240,13 @@ def upload_using_esptool(config, port):
|
||||
*idedata.extra_flash_images,
|
||||
]
|
||||
|
||||
mcu = "esp8266"
|
||||
if CORE.is_esp32:
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
mcu = "esp8266"
|
||||
if CORE.is_esp32:
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
|
||||
mcu = get_esp32_variant().lower()
|
||||
mcu = get_esp32_variant().lower()
|
||||
|
||||
def run_esptool(baud_rate):
|
||||
cmd = [
|
||||
"esptool.py",
|
||||
"--before",
|
||||
@@ -278,20 +285,26 @@ def upload_using_esptool(config, port):
|
||||
return run_esptool(115200)
|
||||
|
||||
|
||||
def upload_using_platformio(config, port):
|
||||
from esphome import platformio_api
|
||||
|
||||
upload_args = ["-t", "upload", "-t", "nobuild"]
|
||||
if port is not None:
|
||||
upload_args += ["--upload-port", port]
|
||||
return platformio_api.run_platformio_cli_run(config, CORE.verbose, *upload_args)
|
||||
|
||||
|
||||
def upload_program(config, args, host):
|
||||
if get_port_type(host) == "SERIAL":
|
||||
if CORE.target_platform in (PLATFORM_ESP32, PLATFORM_ESP8266):
|
||||
return upload_using_esptool(config, host)
|
||||
file = getattr(args, "file", None)
|
||||
return upload_using_esptool(config, host, file)
|
||||
|
||||
if CORE.target_platform in (PLATFORM_RP2040):
|
||||
from esphome import platformio_api
|
||||
return upload_using_platformio(config, args.device)
|
||||
|
||||
upload_args = ["-t", "upload"]
|
||||
if args.device is not None:
|
||||
upload_args += ["--upload-port", args.device]
|
||||
return platformio_api.run_platformio_cli_run(
|
||||
config, CORE.verbose, *upload_args
|
||||
)
|
||||
if CORE.target_platform in (PLATFORM_BK72XX, PLATFORM_RTL87XX):
|
||||
return upload_using_platformio(config, host)
|
||||
|
||||
return 1 # Unknown target platform
|
||||
|
||||
@@ -365,10 +378,16 @@ def command_wizard(args):
|
||||
|
||||
|
||||
def command_config(args, config):
|
||||
_LOGGER.info("Configuration is valid!")
|
||||
if not CORE.verbose:
|
||||
config = strip_default_ids(config)
|
||||
safe_print(yaml_util.dump(config, args.show_secrets))
|
||||
output = yaml_util.dump(config, args.show_secrets)
|
||||
# add the console decoration so the front-end can hide the secrets
|
||||
if not args.show_secrets:
|
||||
output = re.sub(
|
||||
r"(password|key|psk|ssid)\: (.+)", r"\1: \\033[5m\2\\033[6m", output
|
||||
)
|
||||
safe_print(output)
|
||||
_LOGGER.info("Configuration is valid!")
|
||||
return 0
|
||||
|
||||
|
||||
|
@@ -11,6 +11,7 @@ from esphome.const import (
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_TYPE_ID,
|
||||
CONF_TIME,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
)
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||
from esphome.util import Registry
|
||||
@@ -69,6 +70,8 @@ WhileAction = cg.esphome_ns.class_("WhileAction", Action)
|
||||
RepeatAction = cg.esphome_ns.class_("RepeatAction", Action)
|
||||
WaitUntilAction = cg.esphome_ns.class_("WaitUntilAction", Action, cg.Component)
|
||||
UpdateComponentAction = cg.esphome_ns.class_("UpdateComponentAction", Action)
|
||||
SuspendComponentAction = cg.esphome_ns.class_("SuspendComponentAction", Action)
|
||||
ResumeComponentAction = cg.esphome_ns.class_("ResumeComponentAction", Action)
|
||||
Automation = cg.esphome_ns.class_("Automation")
|
||||
|
||||
LambdaCondition = cg.esphome_ns.class_("LambdaCondition", Condition)
|
||||
@@ -138,6 +141,7 @@ AUTOMATION_SCHEMA = cv.Schema(
|
||||
AndCondition = cg.esphome_ns.class_("AndCondition", Condition)
|
||||
OrCondition = cg.esphome_ns.class_("OrCondition", Condition)
|
||||
NotCondition = cg.esphome_ns.class_("NotCondition", Condition)
|
||||
XorCondition = cg.esphome_ns.class_("XorCondition", Condition)
|
||||
|
||||
|
||||
@register_condition("and", AndCondition, validate_condition_list)
|
||||
@@ -158,6 +162,12 @@ async def not_condition_to_code(config, condition_id, template_arg, args):
|
||||
return cg.new_Pvariable(condition_id, template_arg, condition)
|
||||
|
||||
|
||||
@register_condition("xor", XorCondition, validate_condition_list)
|
||||
async def xor_condition_to_code(config, condition_id, template_arg, args):
|
||||
conditions = await build_condition_list(config, template_arg, args)
|
||||
return cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
|
||||
|
||||
@register_condition("lambda", LambdaCondition, cv.returning_lambda)
|
||||
async def lambda_condition_to_code(config, condition_id, template_arg, args):
|
||||
lambda_ = await cg.process_lambda(config, args, return_type=bool)
|
||||
@@ -303,6 +313,41 @@ async def component_update_action_to_code(config, action_id, template_arg, args)
|
||||
return cg.new_Pvariable(action_id, template_arg, comp)
|
||||
|
||||
|
||||
@register_action(
|
||||
"component.suspend",
|
||||
SuspendComponentAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(cg.PollingComponent),
|
||||
}
|
||||
),
|
||||
)
|
||||
async def component_suspend_action_to_code(config, action_id, template_arg, args):
|
||||
comp = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, comp)
|
||||
|
||||
|
||||
@register_action(
|
||||
"component.resume",
|
||||
ResumeComponentAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(cg.PollingComponent),
|
||||
cv.Optional(CONF_UPDATE_INTERVAL): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
}
|
||||
),
|
||||
)
|
||||
async def component_resume_action_to_code(config, action_id, template_arg, args):
|
||||
comp = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, comp)
|
||||
if CONF_UPDATE_INTERVAL in config:
|
||||
template_ = await cg.templatable(config[CONF_UPDATE_INTERVAL], args, int)
|
||||
cg.add(var.set_update_interval(template_))
|
||||
return var
|
||||
|
||||
|
||||
async def build_action(full_config, template_arg, args):
|
||||
registry_entry, config = cg.extract_registry_entry_config(
|
||||
ACTION_REGISTRY, full_config
|
||||
|
1
esphome/components/a01nyub/__init__.py
Normal file
1
esphome/components/a01nyub/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
CODEOWNERS = ["@MrSuicideParrot"]
|
57
esphome/components/a01nyub/a01nyub.cpp
Normal file
57
esphome/components/a01nyub/a01nyub.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Datasheet https://wiki.dfrobot.com/A01NYUB%20Waterproof%20Ultrasonic%20Sensor%20SKU:%20SEN0313
|
||||
|
||||
#include "a01nyub.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace a01nyub {
|
||||
|
||||
static const char *const TAG = "a01nyub.sensor";
|
||||
static const uint8_t MAX_DATA_LENGTH_BYTES = 4;
|
||||
|
||||
void A01nyubComponent::loop() {
|
||||
uint8_t data;
|
||||
while (this->available() > 0) {
|
||||
if (this->read_byte(&data)) {
|
||||
buffer_.push_back(data);
|
||||
this->check_buffer_();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void A01nyubComponent::check_buffer_() {
|
||||
if (this->buffer_.size() >= MAX_DATA_LENGTH_BYTES) {
|
||||
size_t i;
|
||||
for (i = 0; i < this->buffer_.size(); i++) {
|
||||
// Look for the first packet
|
||||
if (this->buffer_[i] == 0xFF) {
|
||||
if (i + 1 + 3 < this->buffer_.size()) { // Packet is not complete
|
||||
return; // Wait for completion
|
||||
}
|
||||
|
||||
uint8_t checksum = (this->buffer_[i] + this->buffer_[i + 1] + this->buffer_[i + 2]) & 0xFF;
|
||||
if (this->buffer_[i + 3] == checksum) {
|
||||
float distance = (this->buffer_[i + 1] << 8) + this->buffer_[i + 2];
|
||||
if (distance > 280) {
|
||||
float meters = distance / 1000.0;
|
||||
ESP_LOGV(TAG, "Distance from sensor: %f mm, %f m", distance, meters);
|
||||
this->publish_state(meters);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->buffer_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void A01nyubComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "A01nyub Sensor:");
|
||||
LOG_SENSOR(" ", "Distance", this);
|
||||
}
|
||||
|
||||
} // namespace a01nyub
|
||||
} // namespace esphome
|
27
esphome/components/a01nyub/a01nyub.h
Normal file
27
esphome/components/a01nyub/a01nyub.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace a01nyub {
|
||||
|
||||
class A01nyubComponent : public sensor::Sensor, public Component, public uart::UARTDevice {
|
||||
public:
|
||||
// Nothing really public.
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
void check_buffer_();
|
||||
|
||||
std::vector<uint8_t> buffer_;
|
||||
};
|
||||
|
||||
} // namespace a01nyub
|
||||
} // namespace esphome
|
41
esphome/components/a01nyub/sensor.py
Normal file
41
esphome/components/a01nyub/sensor.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor, uart
|
||||
from esphome.const import (
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_METER,
|
||||
ICON_ARROW_EXPAND_VERTICAL,
|
||||
DEVICE_CLASS_DISTANCE,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@MrSuicideParrot"]
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
a01nyub_ns = cg.esphome_ns.namespace("a01nyub")
|
||||
A01nyubComponent = a01nyub_ns.class_(
|
||||
"A01nyubComponent", sensor.Sensor, cg.Component, uart.UARTDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
A01nyubComponent,
|
||||
unit_of_measurement=UNIT_METER,
|
||||
icon=ICON_ARROW_EXPAND_VERTICAL,
|
||||
accuracy_decimals=3,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
device_class=DEVICE_CLASS_DISTANCE,
|
||||
).extend(uart.UART_DEVICE_SCHEMA)
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
|
||||
"a01nyub",
|
||||
baud_rate=9600,
|
||||
require_tx=False,
|
||||
require_rx=True,
|
||||
data_bits=8,
|
||||
parity=None,
|
||||
stop_bits=1,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
await uart.register_uart_device(var, config)
|
@@ -28,6 +28,6 @@ async def to_code(config):
|
||||
dir_pin = await cg.gpio_pin_expression(config[CONF_DIR_PIN])
|
||||
cg.add(var.set_dir_pin(dir_pin))
|
||||
|
||||
if CONF_SLEEP_PIN in config:
|
||||
sleep_pin = await cg.gpio_pin_expression(config[CONF_SLEEP_PIN])
|
||||
if sleep_pin_config := config.get(CONF_SLEEP_PIN):
|
||||
sleep_pin = await cg.gpio_pin_expression(sleep_pin_config)
|
||||
cg.add(var.set_sleep_pin(sleep_pin))
|
||||
|
@@ -1,13 +1,16 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_INPUT
|
||||
from esphome.const import CONF_ANALOG, CONF_INPUT
|
||||
|
||||
from esphome.core import CORE
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
from esphome.const import PLATFORM_ESP8266
|
||||
from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
@@ -70,6 +73,22 @@ ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
|
||||
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||
},
|
||||
VARIANT_ESP32C2: {
|
||||
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||
2: adc1_channel_t.ADC1_CHANNEL_2,
|
||||
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||
},
|
||||
VARIANT_ESP32C6: {
|
||||
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||
2: adc1_channel_t.ADC1_CHANNEL_2,
|
||||
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||
5: adc1_channel_t.ADC1_CHANNEL_5,
|
||||
6: adc1_channel_t.ADC1_CHANNEL_6,
|
||||
},
|
||||
VARIANT_ESP32H2: {
|
||||
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||
@@ -125,7 +144,9 @@ ESP32_VARIANT_ADC2_PIN_TO_CHANNEL = {
|
||||
|
||||
def validate_adc_pin(value):
|
||||
if str(value).upper() == "VCC":
|
||||
return cv.only_on_esp8266("VCC")
|
||||
if CORE.is_rp2040:
|
||||
return pins.internal_gpio_input_pin_schema(29)
|
||||
return cv.only_on([PLATFORM_ESP8266])("VCC")
|
||||
|
||||
if str(value).upper() == "TEMPERATURE":
|
||||
return cv.only_on_rp2040("TEMPERATURE")
|
||||
@@ -148,8 +169,6 @@ def validate_adc_pin(value):
|
||||
return pins.internal_gpio_input_pin_schema(value)
|
||||
|
||||
if CORE.is_esp8266:
|
||||
from esphome.components.esp8266.gpio import CONF_ANALOG
|
||||
|
||||
value = pins.internal_gpio_pin_number({CONF_ANALOG: True, CONF_INPUT: True})(
|
||||
value
|
||||
)
|
||||
@@ -166,4 +185,9 @@ def validate_adc_pin(value):
|
||||
raise cv.Invalid("RP2040: Only pins 26, 27, 28 and 29 support ADC")
|
||||
return pins.internal_gpio_input_pin_schema(value)
|
||||
|
||||
if CORE.is_libretiny:
|
||||
return pins.gpio_pin_schema(
|
||||
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
|
||||
)(value)
|
||||
|
||||
raise NotImplementedError
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include "adc_sensor.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
#ifdef USE_ADC_SENSOR_VCC
|
||||
@@ -12,6 +12,9 @@ ADC_MODE(ADC_VCC)
|
||||
#endif
|
||||
|
||||
#ifdef USE_RP2040
|
||||
#ifdef CYW43_USES_VSYS_PIN
|
||||
#include "pico/cyw43_arch.h"
|
||||
#endif
|
||||
#include <hardware/adc.h>
|
||||
#endif
|
||||
|
||||
@@ -92,13 +95,13 @@ extern "C"
|
||||
|
||||
void ADCSensor::dump_config() {
|
||||
LOG_SENSOR("", "ADC Sensor", this);
|
||||
#ifdef USE_ESP8266
|
||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
||||
#ifdef USE_ADC_SENSOR_VCC
|
||||
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||
#else
|
||||
LOG_PIN(" Pin: ", pin_);
|
||||
#endif
|
||||
#endif // USE_ESP8266
|
||||
#endif // USE_ESP8266 || USE_LIBRETINY
|
||||
|
||||
#ifdef USE_ESP32
|
||||
LOG_PIN(" Pin: ", pin_);
|
||||
@@ -123,13 +126,19 @@ void ADCSensor::dump_config() {
|
||||
}
|
||||
}
|
||||
#endif // USE_ESP32
|
||||
|
||||
#ifdef USE_RP2040
|
||||
if (this->is_temperature_) {
|
||||
ESP_LOGCONFIG(TAG, " Pin: Temperature");
|
||||
} else {
|
||||
#ifdef USE_ADC_SENSOR_VCC
|
||||
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||
#else
|
||||
LOG_PIN(" Pin: ", pin_);
|
||||
#endif // USE_ADC_SENSOR_VCC
|
||||
}
|
||||
#endif
|
||||
#endif // USE_RP2040
|
||||
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
@@ -237,23 +246,54 @@ float ADCSensor::sample() {
|
||||
adc_set_temp_sensor_enabled(true);
|
||||
delay(1);
|
||||
adc_select_input(4);
|
||||
|
||||
int32_t raw = adc_read();
|
||||
adc_set_temp_sensor_enabled(false);
|
||||
if (this->output_raw_) {
|
||||
return raw;
|
||||
}
|
||||
return raw * 3.3f / 4096.0f;
|
||||
} else {
|
||||
uint8_t pin = this->pin_->get_pin();
|
||||
#ifdef CYW43_USES_VSYS_PIN
|
||||
if (pin == PICO_VSYS_PIN) {
|
||||
// Measuring VSYS on Raspberry Pico W needs to be wrapped with
|
||||
// `cyw43_thread_enter()`/`cyw43_thread_exit()` as discussed in
|
||||
// https://github.com/raspberrypi/pico-sdk/issues/1222, since Wifi chip and
|
||||
// VSYS ADC both share GPIO29
|
||||
cyw43_thread_enter();
|
||||
}
|
||||
#endif // CYW43_USES_VSYS_PIN
|
||||
|
||||
adc_gpio_init(pin);
|
||||
adc_select_input(pin - 26);
|
||||
}
|
||||
|
||||
int32_t raw = adc_read();
|
||||
if (this->is_temperature_) {
|
||||
adc_set_temp_sensor_enabled(false);
|
||||
int32_t raw = adc_read();
|
||||
|
||||
#ifdef CYW43_USES_VSYS_PIN
|
||||
if (pin == PICO_VSYS_PIN) {
|
||||
cyw43_thread_exit();
|
||||
}
|
||||
#endif // CYW43_USES_VSYS_PIN
|
||||
|
||||
if (output_raw_) {
|
||||
return raw;
|
||||
}
|
||||
float coeff = pin == PICO_VSYS_PIN ? 3.0 : 1.0;
|
||||
return raw * 3.3f / 4096.0f * coeff;
|
||||
}
|
||||
if (output_raw_) {
|
||||
return raw;
|
||||
}
|
||||
return raw * 3.3f / 4096.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBRETINY
|
||||
float ADCSensor::sample() {
|
||||
if (output_raw_) {
|
||||
return analogRead(this->pin_->get_pin()); // NOLINT
|
||||
}
|
||||
return analogReadVoltage(this->pin_->get_pin()) / 1000.0f; // NOLINT
|
||||
}
|
||||
#endif // USE_LIBRETINY
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
|
||||
#endif
|
||||
|
@@ -62,8 +62,12 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||
adc1_channel_t channel1_{ADC1_CHANNEL_MAX};
|
||||
adc2_channel_t channel2_{ADC2_CHANNEL_MAX};
|
||||
bool autorange_{false};
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM] = {};
|
||||
#else
|
||||
esp_adc_cal_characteristics_t cal_characteristics_[ADC_ATTEN_MAX] = {};
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace adc
|
||||
|
@@ -89,14 +89,13 @@ async def to_code(config):
|
||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||
cg.add(var.set_pin(pin))
|
||||
|
||||
if CONF_RAW in config:
|
||||
cg.add(var.set_output_raw(config[CONF_RAW]))
|
||||
cg.add(var.set_output_raw(config[CONF_RAW]))
|
||||
|
||||
if CONF_ATTENUATION in config:
|
||||
if config[CONF_ATTENUATION] == "auto":
|
||||
if attenuation := config.get(CONF_ATTENUATION):
|
||||
if attenuation == "auto":
|
||||
cg.add(var.set_autorange(cg.global_ns.true))
|
||||
else:
|
||||
cg.add(var.set_attenuation(config[CONF_ATTENUATION]))
|
||||
cg.add(var.set_attenuation(attenuation))
|
||||
|
||||
if CORE.is_esp32:
|
||||
variant = get_esp32_variant()
|
||||
|
@@ -48,16 +48,16 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await display.register_display(var, config)
|
||||
|
||||
if CONF_PIXEL_MAPPER in config:
|
||||
if pixel_mapper := config.get(CONF_PIXEL_MAPPER):
|
||||
pixel_mapper_template_ = await cg.process_lambda(
|
||||
config[CONF_PIXEL_MAPPER],
|
||||
pixel_mapper,
|
||||
[(int, "x"), (int, "y")],
|
||||
return_type=cg.int_,
|
||||
)
|
||||
cg.add(var.set_pixel_mapper(pixel_mapper_template_))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
if lambda_config := config.get(CONF_LAMBDA):
|
||||
lambda_ = await cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
|
||||
lambda_config, [(display.DisplayRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
@@ -4,13 +4,14 @@ from esphome.components import sensor, i2c
|
||||
from esphome import pins
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_IRQ_PIN,
|
||||
CONF_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_VOLT,
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
@@ -19,7 +20,6 @@ DEPENDENCIES = ["i2c"]
|
||||
ade7953_ns = cg.esphome_ns.namespace("ade7953")
|
||||
ADE7953 = ade7953_ns.class_("ADE7953", cg.PollingComponent, i2c.I2CDevice)
|
||||
|
||||
CONF_IRQ_PIN = "irq_pin"
|
||||
CONF_CURRENT_A = "current_a"
|
||||
CONF_CURRENT_B = "current_b"
|
||||
CONF_ACTIVE_POWER_A = "active_power_a"
|
||||
@@ -72,8 +72,8 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_IRQ_PIN in config:
|
||||
irq_pin = await cg.gpio_pin_expression(config[CONF_IRQ_PIN])
|
||||
if irq_pin_config := config.get(CONF_IRQ_PIN):
|
||||
irq_pin = await cg.gpio_pin_expression(irq_pin_config)
|
||||
cg.add(var.set_irq_pin(irq_pin))
|
||||
|
||||
for key in [
|
||||
|
@@ -45,10 +45,10 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
if temperature := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
|
||||
if CONF_HUMIDITY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_HUMIDITY])
|
||||
if humidity := config.get(CONF_HUMIDITY):
|
||||
sens = await sensor.new_sensor(humidity)
|
||||
cg.add(var.set_humidity_sensor(sens))
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "airthings_listener.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cinttypes>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
@@ -19,7 +20,7 @@ bool AirthingsListener::parse_device(const esp32_ble_tracker::ESPBTDevice &devic
|
||||
sn |= ((uint32_t) it.data[2] << 16);
|
||||
sn |= ((uint32_t) it.data[3] << 24);
|
||||
|
||||
ESP_LOGD(TAG, "Found AirThings device Serial:%u (MAC: %s)", sn, device.address_str().c_str());
|
||||
ESP_LOGD(TAG, "Found AirThings device Serial:%" PRIu32 " (MAC: %s)", sn, device.address_str().c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,12 @@ IS_PLATFORM_COMPONENT = True
|
||||
|
||||
CONF_ON_TRIGGERED = "on_triggered"
|
||||
CONF_ON_CLEARED = "on_cleared"
|
||||
CONF_ON_ARMING = "on_arming"
|
||||
CONF_ON_PENDING = "on_pending"
|
||||
CONF_ON_ARMED_HOME = "on_armed_home"
|
||||
CONF_ON_ARMED_NIGHT = "on_armed_night"
|
||||
CONF_ON_ARMED_AWAY = "on_armed_away"
|
||||
CONF_ON_DISARMED = "on_disarmed"
|
||||
|
||||
alarm_control_panel_ns = cg.esphome_ns.namespace("alarm_control_panel")
|
||||
AlarmControlPanel = alarm_control_panel_ns.class_("AlarmControlPanel", cg.EntityBase)
|
||||
@@ -29,8 +35,27 @@ TriggeredTrigger = alarm_control_panel_ns.class_(
|
||||
ClearedTrigger = alarm_control_panel_ns.class_(
|
||||
"ClearedTrigger", automation.Trigger.template()
|
||||
)
|
||||
ArmingTrigger = alarm_control_panel_ns.class_(
|
||||
"ArmingTrigger", automation.Trigger.template()
|
||||
)
|
||||
PendingTrigger = alarm_control_panel_ns.class_(
|
||||
"PendingTrigger", automation.Trigger.template()
|
||||
)
|
||||
ArmedHomeTrigger = alarm_control_panel_ns.class_(
|
||||
"ArmedHomeTrigger", automation.Trigger.template()
|
||||
)
|
||||
ArmedNightTrigger = alarm_control_panel_ns.class_(
|
||||
"ArmedNightTrigger", automation.Trigger.template()
|
||||
)
|
||||
ArmedAwayTrigger = alarm_control_panel_ns.class_(
|
||||
"ArmedAwayTrigger", automation.Trigger.template()
|
||||
)
|
||||
DisarmedTrigger = alarm_control_panel_ns.class_(
|
||||
"DisarmedTrigger", automation.Trigger.template()
|
||||
)
|
||||
ArmAwayAction = alarm_control_panel_ns.class_("ArmAwayAction", automation.Action)
|
||||
ArmHomeAction = alarm_control_panel_ns.class_("ArmHomeAction", automation.Action)
|
||||
ArmNightAction = alarm_control_panel_ns.class_("ArmNightAction", automation.Action)
|
||||
DisarmAction = alarm_control_panel_ns.class_("DisarmAction", automation.Action)
|
||||
PendingAction = alarm_control_panel_ns.class_("PendingAction", automation.Action)
|
||||
TriggeredAction = alarm_control_panel_ns.class_("TriggeredAction", automation.Action)
|
||||
@@ -51,6 +76,36 @@ ALARM_CONTROL_PANEL_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(TriggeredTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_ARMING): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ArmingTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_PENDING): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PendingTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_ARMED_HOME): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ArmedHomeTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_ARMED_NIGHT): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ArmedNightTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_ARMED_AWAY): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ArmedAwayTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_DISARMED): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DisarmedTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_CLEARED): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ClearedTrigger),
|
||||
@@ -81,6 +136,24 @@ async def setup_alarm_control_panel_core_(var, config):
|
||||
for conf in config.get(CONF_ON_TRIGGERED, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_ARMING, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_PENDING, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_ARMED_HOME, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_ARMED_NIGHT, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_ARMED_AWAY, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_DISARMED, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
for conf in config.get(CONF_ON_CLEARED, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
@@ -99,8 +172,8 @@ async def register_alarm_control_panel(var, config):
|
||||
async def alarm_action_arm_away_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
if CONF_CODE in config:
|
||||
templatable_ = await cg.templatable(config[CONF_CODE], args, cg.std_string)
|
||||
if code_config := config.get(CONF_CODE):
|
||||
templatable_ = await cg.templatable(code_config, args, cg.std_string)
|
||||
cg.add(var.set_code(templatable_))
|
||||
return var
|
||||
|
||||
@@ -109,6 +182,18 @@ async def alarm_action_arm_away_to_code(config, action_id, template_arg, args):
|
||||
"alarm_control_panel.arm_home", ArmHomeAction, ALARM_CONTROL_PANEL_ACTION_SCHEMA
|
||||
)
|
||||
async def alarm_action_arm_home_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
if code_config := config.get(CONF_CODE):
|
||||
templatable_ = await cg.templatable(code_config, args, cg.std_string)
|
||||
cg.add(var.set_code(templatable_))
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"alarm_control_panel.arm_night", ArmNightAction, ALARM_CONTROL_PANEL_ACTION_SCHEMA
|
||||
)
|
||||
async def alarm_action_arm_night_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
if CONF_CODE in config:
|
||||
@@ -123,8 +208,8 @@ async def alarm_action_arm_home_to_code(config, action_id, template_arg, args):
|
||||
async def alarm_action_disarm_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
if CONF_CODE in config:
|
||||
templatable_ = await cg.templatable(config[CONF_CODE], args, cg.std_string)
|
||||
if code_config := config.get(CONF_CODE):
|
||||
templatable_ = await cg.templatable(code_config, args, cg.std_string)
|
||||
cg.add(var.set_code(templatable_))
|
||||
return var
|
||||
|
||||
|
@@ -36,7 +36,20 @@ void AlarmControlPanel::publish_state(AlarmControlPanelState state) {
|
||||
this->state_callback_.call();
|
||||
if (state == ACP_STATE_TRIGGERED) {
|
||||
this->triggered_callback_.call();
|
||||
} else if (state == ACP_STATE_ARMING) {
|
||||
this->arming_callback_.call();
|
||||
} else if (state == ACP_STATE_PENDING) {
|
||||
this->pending_callback_.call();
|
||||
} else if (state == ACP_STATE_ARMED_HOME) {
|
||||
this->armed_home_callback_.call();
|
||||
} else if (state == ACP_STATE_ARMED_NIGHT) {
|
||||
this->armed_night_callback_.call();
|
||||
} else if (state == ACP_STATE_ARMED_AWAY) {
|
||||
this->armed_away_callback_.call();
|
||||
} else if (state == ACP_STATE_DISARMED) {
|
||||
this->disarmed_callback_.call();
|
||||
}
|
||||
|
||||
if (prev_state == ACP_STATE_TRIGGERED) {
|
||||
this->cleared_callback_.call();
|
||||
}
|
||||
@@ -55,6 +68,30 @@ void AlarmControlPanel::add_on_triggered_callback(std::function<void()> &&callba
|
||||
this->triggered_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_arming_callback(std::function<void()> &&callback) {
|
||||
this->arming_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_armed_home_callback(std::function<void()> &&callback) {
|
||||
this->armed_home_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_armed_night_callback(std::function<void()> &&callback) {
|
||||
this->armed_night_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_armed_away_callback(std::function<void()> &&callback) {
|
||||
this->armed_away_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_pending_callback(std::function<void()> &&callback) {
|
||||
this->pending_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_disarmed_callback(std::function<void()> &&callback) {
|
||||
this->disarmed_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void AlarmControlPanel::add_on_cleared_callback(std::function<void()> &&callback) {
|
||||
this->cleared_callback_.add(std::move(callback));
|
||||
}
|
||||
|
@@ -47,6 +47,42 @@ class AlarmControlPanel : public EntityBase {
|
||||
*/
|
||||
void add_on_triggered_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel chanes to arming
|
||||
*
|
||||
* @param callback The callback function
|
||||
*/
|
||||
void add_on_arming_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel changes to pending
|
||||
*
|
||||
* @param callback The callback function
|
||||
*/
|
||||
void add_on_pending_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel changes to armed_home
|
||||
*
|
||||
* @param callback The callback function
|
||||
*/
|
||||
void add_on_armed_home_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel changes to armed_night
|
||||
*
|
||||
* @param callback The callback function
|
||||
*/
|
||||
void add_on_armed_night_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel changes to armed_away
|
||||
*
|
||||
* @param callback The callback function
|
||||
*/
|
||||
void add_on_armed_away_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel changes to disarmed
|
||||
*
|
||||
* @param callback The callback function
|
||||
*/
|
||||
void add_on_disarmed_callback(std::function<void()> &&callback);
|
||||
|
||||
/** Add a callback for when the state of the alarm_control_panel clears from triggered
|
||||
*
|
||||
* @param callback The callback function
|
||||
@@ -128,6 +164,18 @@ class AlarmControlPanel : public EntityBase {
|
||||
CallbackManager<void()> state_callback_{};
|
||||
// trigger callback
|
||||
CallbackManager<void()> triggered_callback_{};
|
||||
// arming callback
|
||||
CallbackManager<void()> arming_callback_{};
|
||||
// pending callback
|
||||
CallbackManager<void()> pending_callback_{};
|
||||
// armed_home callback
|
||||
CallbackManager<void()> armed_home_callback_{};
|
||||
// armed_night callback
|
||||
CallbackManager<void()> armed_night_callback_{};
|
||||
// armed_away callback
|
||||
CallbackManager<void()> armed_away_callback_{};
|
||||
// disarmed callback
|
||||
CallbackManager<void()> disarmed_callback_{};
|
||||
// clear callback
|
||||
CallbackManager<void()> cleared_callback_{};
|
||||
};
|
||||
|
@@ -85,6 +85,11 @@ void AlarmControlPanelCall::validate_() {
|
||||
this->state_.reset();
|
||||
return;
|
||||
}
|
||||
if (state == ACP_STATE_ARMED_NIGHT && (this->parent_->get_supported_features() & ACP_FEAT_ARM_NIGHT) == 0) {
|
||||
ESP_LOGW(TAG, "Cannot arm night when not supported");
|
||||
this->state_.reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@ const LogString *alarm_control_panel_state_to_string(AlarmControlPanelState stat
|
||||
case ACP_STATE_ARMED_AWAY:
|
||||
return LOG_STR("ARMED_AWAY");
|
||||
case ACP_STATE_ARMED_NIGHT:
|
||||
return LOG_STR("NIGHT");
|
||||
return LOG_STR("ARMED_NIGHT");
|
||||
case ACP_STATE_ARMED_VACATION:
|
||||
return LOG_STR("ARMED_VACATION");
|
||||
case ACP_STATE_ARMED_CUSTOM_BYPASS:
|
||||
|
@@ -20,6 +20,48 @@ class TriggeredTrigger : public Trigger<> {
|
||||
}
|
||||
};
|
||||
|
||||
class ArmingTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit ArmingTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
alarm_control_panel->add_on_arming_callback([this]() { this->trigger(); });
|
||||
}
|
||||
};
|
||||
|
||||
class PendingTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit PendingTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
alarm_control_panel->add_on_pending_callback([this]() { this->trigger(); });
|
||||
}
|
||||
};
|
||||
|
||||
class ArmedHomeTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit ArmedHomeTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
alarm_control_panel->add_on_armed_home_callback([this]() { this->trigger(); });
|
||||
}
|
||||
};
|
||||
|
||||
class ArmedNightTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit ArmedNightTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
alarm_control_panel->add_on_armed_night_callback([this]() { this->trigger(); });
|
||||
}
|
||||
};
|
||||
|
||||
class ArmedAwayTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit ArmedAwayTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
alarm_control_panel->add_on_armed_away_callback([this]() { this->trigger(); });
|
||||
}
|
||||
};
|
||||
|
||||
class DisarmedTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit DisarmedTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
alarm_control_panel->add_on_disarmed_callback([this]() { this->trigger(); });
|
||||
}
|
||||
};
|
||||
|
||||
class ClearedTrigger : public Trigger<> {
|
||||
public:
|
||||
explicit ClearedTrigger(AlarmControlPanel *alarm_control_panel) {
|
||||
@@ -67,6 +109,26 @@ template<typename... Ts> class ArmHomeAction : public Action<Ts...> {
|
||||
AlarmControlPanel *alarm_control_panel_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class ArmNightAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit ArmNightAction(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {}
|
||||
|
||||
TEMPLATABLE_VALUE(std::string, code)
|
||||
|
||||
void play(Ts... x) override {
|
||||
auto call = this->alarm_control_panel_->make_call();
|
||||
auto code = this->code_.optional_value(x...);
|
||||
if (code.has_value()) {
|
||||
call.set_code(code.value());
|
||||
}
|
||||
call.arm_night();
|
||||
call.perform();
|
||||
}
|
||||
|
||||
protected:
|
||||
AlarmControlPanel *alarm_control_panel_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class DisarmAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit DisarmAction(AlarmControlPanel *alarm_control_panel) : alarm_control_panel_(alarm_control_panel) {}
|
||||
|
@@ -60,26 +60,26 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await ble_client.register_ble_node(var, config)
|
||||
|
||||
if CONF_FLOW in config:
|
||||
sens = await sensor.new_sensor(config[CONF_FLOW])
|
||||
if flow_config := config.get(CONF_FLOW):
|
||||
sens = await sensor.new_sensor(flow_config)
|
||||
cg.add(var.set_flow_sensor(sens))
|
||||
|
||||
if CONF_HEAD in config:
|
||||
sens = await sensor.new_sensor(config[CONF_HEAD])
|
||||
if head_config := config.get(CONF_HEAD):
|
||||
sens = await sensor.new_sensor(head_config)
|
||||
cg.add(var.set_head_sensor(sens))
|
||||
|
||||
if CONF_POWER in config:
|
||||
sens = await sensor.new_sensor(config[CONF_POWER])
|
||||
if power_config := config.get(CONF_POWER):
|
||||
sens = await sensor.new_sensor(power_config)
|
||||
cg.add(var.set_power_sensor(sens))
|
||||
|
||||
if CONF_CURRENT in config:
|
||||
sens = await sensor.new_sensor(config[CONF_CURRENT])
|
||||
if current_config := config.get(CONF_CURRENT):
|
||||
sens = await sensor.new_sensor(current_config)
|
||||
cg.add(var.set_current_sensor(sens))
|
||||
|
||||
if CONF_SPEED in config:
|
||||
sens = await sensor.new_sensor(config[CONF_SPEED])
|
||||
if speed_config := config.get(CONF_SPEED):
|
||||
sens = await sensor.new_sensor(speed_config)
|
||||
cg.add(var.set_speed_sensor(sens))
|
||||
|
||||
if CONF_VOLTAGE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_VOLTAGE])
|
||||
if voltage_config := config.get(CONF_VOLTAGE):
|
||||
sens = await sensor.new_sensor(voltage_config)
|
||||
cg.add(var.set_voltage_sensor(sens))
|
||||
|
@@ -47,10 +47,10 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
|
||||
if CONF_HUMIDITY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_HUMIDITY])
|
||||
if humidity_config := config.get(CONF_HUMIDITY):
|
||||
sens = await sensor.new_sensor(humidity_config)
|
||||
cg.add(var.set_humidity_sensor(sens))
|
||||
|
@@ -44,10 +44,10 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await ble_client.register_ble_node(var, config)
|
||||
|
||||
if CONF_BATTERY_LEVEL in config:
|
||||
sens = await sensor.new_sensor(config[CONF_BATTERY_LEVEL])
|
||||
if battery_level_config := config.get(CONF_BATTERY_LEVEL):
|
||||
sens = await sensor.new_sensor(battery_level_config)
|
||||
cg.add(var.set_battery(sens))
|
||||
|
||||
if CONF_ILLUMINANCE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_ILLUMINANCE])
|
||||
if illuminance_config := config.get(CONF_ILLUMINANCE):
|
||||
sens = await sensor.new_sensor(illuminance_config)
|
||||
cg.add(var.set_illuminance(sens))
|
||||
|
@@ -115,8 +115,8 @@ async def animation_action_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
if CONF_FRAME in config:
|
||||
template_ = await cg.templatable(config[CONF_FRAME], args, cg.uint16)
|
||||
if (frame := config.get(CONF_FRAME)) is not None:
|
||||
template_ = await cg.templatable(frame, args, cg.uint16)
|
||||
cg.add(var.set_frame(template_))
|
||||
return var
|
||||
|
||||
@@ -151,7 +151,7 @@ async def to_code(config):
|
||||
pos = 0
|
||||
for frameIndex in range(frames):
|
||||
image.seek(frameIndex)
|
||||
frame = image.convert("LA", dither=Image.NONE)
|
||||
frame = image.convert("LA", dither=Image.Dither.NONE)
|
||||
if CONF_RESIZE in config:
|
||||
frame = frame.resize([width, height])
|
||||
pixels = list(frame.getdata())
|
||||
@@ -259,7 +259,7 @@ async def to_code(config):
|
||||
if transparent:
|
||||
alpha = image.split()[-1]
|
||||
has_alpha = alpha.getextrema()[0] < 0xFF
|
||||
frame = image.convert("1", dither=Image.NONE)
|
||||
frame = image.convert("1", dither=Image.Dither.NONE)
|
||||
if CONF_RESIZE in config:
|
||||
frame = frame.resize([width, height])
|
||||
if transparent:
|
||||
@@ -289,8 +289,8 @@ async def to_code(config):
|
||||
espImage.IMAGE_TYPE[config[CONF_TYPE]],
|
||||
)
|
||||
cg.add(var.set_transparency(transparent))
|
||||
if CONF_LOOP in config:
|
||||
start = config[CONF_LOOP][CONF_START_FRAME]
|
||||
end = config[CONF_LOOP].get(CONF_END_FRAME, frames)
|
||||
count = config[CONF_LOOP].get(CONF_REPEAT, -1)
|
||||
if loop_config := config.get(CONF_LOOP):
|
||||
start = loop_config[CONF_START_FRAME]
|
||||
end = loop_config.get(CONF_END_FRAME, frames)
|
||||
count = loop_config.get(CONF_REPEAT, -1)
|
||||
cg.add(var.set_loop(start, end, count))
|
||||
|
@@ -116,9 +116,8 @@ async def to_code(config):
|
||||
cg.add(var.register_user_service(trigger))
|
||||
await automation.build_automation(trigger, func_args, conf)
|
||||
|
||||
if CONF_ENCRYPTION in config:
|
||||
conf = config[CONF_ENCRYPTION]
|
||||
decoded = base64.b64decode(conf[CONF_KEY])
|
||||
if encryption_config := config.get(CONF_ENCRYPTION):
|
||||
decoded = base64.b64decode(encryption_config[CONF_KEY])
|
||||
cg.add(var.set_noise_psk(list(decoded)))
|
||||
cg.add_define("USE_API_NOISE")
|
||||
cg.add_library("esphome/noise-c", "0.1.4")
|
||||
|
@@ -1413,6 +1413,18 @@ message SubscribeVoiceAssistantRequest {
|
||||
bool subscribe = 1;
|
||||
}
|
||||
|
||||
enum VoiceAssistantRequestFlag {
|
||||
VOICE_ASSISTANT_REQUEST_NONE = 0;
|
||||
VOICE_ASSISTANT_REQUEST_USE_VAD = 1;
|
||||
VOICE_ASSISTANT_REQUEST_USE_WAKE_WORD = 2;
|
||||
}
|
||||
|
||||
message VoiceAssistantAudioSettings {
|
||||
uint32 noise_suppression_level = 1;
|
||||
uint32 auto_gain = 2;
|
||||
float volume_multiplier = 3;
|
||||
}
|
||||
|
||||
message VoiceAssistantRequest {
|
||||
option (id) = 90;
|
||||
option (source) = SOURCE_SERVER;
|
||||
@@ -1420,7 +1432,8 @@ message VoiceAssistantRequest {
|
||||
|
||||
bool start = 1;
|
||||
string conversation_id = 2;
|
||||
bool use_vad = 3;
|
||||
uint32 flags = 3;
|
||||
VoiceAssistantAudioSettings audio_settings = 4;
|
||||
}
|
||||
|
||||
message VoiceAssistantResponse {
|
||||
@@ -1442,6 +1455,12 @@ enum VoiceAssistantEvent {
|
||||
VOICE_ASSISTANT_INTENT_END = 6;
|
||||
VOICE_ASSISTANT_TTS_START = 7;
|
||||
VOICE_ASSISTANT_TTS_END = 8;
|
||||
VOICE_ASSISTANT_WAKE_WORD_START = 9;
|
||||
VOICE_ASSISTANT_WAKE_WORD_END = 10;
|
||||
VOICE_ASSISTANT_STT_VAD_START = 11;
|
||||
VOICE_ASSISTANT_STT_VAD_END = 12;
|
||||
VOICE_ASSISTANT_TTS_STREAM_START = 98;
|
||||
VOICE_ASSISTANT_TTS_STREAM_END = 99;
|
||||
}
|
||||
|
||||
message VoiceAssistantEventData {
|
||||
|
@@ -907,21 +907,22 @@ BluetoothConnectionsFreeResponse APIConnection::subscribe_bluetooth_connections_
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOICE_ASSISTANT
|
||||
bool APIConnection::request_voice_assistant(bool start, const std::string &conversation_id, bool use_vad) {
|
||||
bool APIConnection::request_voice_assistant(const VoiceAssistantRequest &msg) {
|
||||
if (!this->voice_assistant_subscription_)
|
||||
return false;
|
||||
VoiceAssistantRequest msg;
|
||||
msg.start = start;
|
||||
msg.conversation_id = conversation_id;
|
||||
msg.use_vad = use_vad;
|
||||
|
||||
return this->send_voice_assistant_request(msg);
|
||||
}
|
||||
void APIConnection::on_voice_assistant_response(const VoiceAssistantResponse &msg) {
|
||||
if (voice_assistant::global_voice_assistant != nullptr) {
|
||||
if (msg.error) {
|
||||
voice_assistant::global_voice_assistant->failed_to_start();
|
||||
return;
|
||||
}
|
||||
struct sockaddr_storage storage;
|
||||
socklen_t len = sizeof(storage);
|
||||
this->helper_->getpeername((struct sockaddr *) &storage, &len);
|
||||
voice_assistant::global_voice_assistant->start(&storage, msg.port);
|
||||
voice_assistant::global_voice_assistant->start_streaming(&storage, msg.port);
|
||||
}
|
||||
};
|
||||
void APIConnection::on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) {
|
||||
@@ -1051,6 +1052,10 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
||||
resp.manufacturer = "Espressif";
|
||||
#elif defined(USE_RP2040)
|
||||
resp.manufacturer = "Raspberry Pi";
|
||||
#elif defined(USE_BK72XX)
|
||||
resp.manufacturer = "Beken";
|
||||
#elif defined(USE_RTL87XX)
|
||||
resp.manufacturer = "Realtek";
|
||||
#elif defined(USE_HOST)
|
||||
resp.manufacturer = "Host";
|
||||
#endif
|
||||
|
@@ -124,7 +124,7 @@ class APIConnection : public APIServerConnection {
|
||||
void subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) override {
|
||||
this->voice_assistant_subscription_ = msg.subscribe;
|
||||
}
|
||||
bool request_voice_assistant(bool start, const std::string &conversation_id, bool use_vad);
|
||||
bool request_voice_assistant(const VoiceAssistantRequest &msg);
|
||||
void on_voice_assistant_response(const VoiceAssistantResponse &msg) override;
|
||||
void on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) override;
|
||||
#endif
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include "api_pb2.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace api {
|
||||
|
||||
@@ -408,6 +410,20 @@ const char *proto_enum_to_string<enums::BluetoothDeviceRequestType>(enums::Bluet
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::VoiceAssistantRequestFlag>(enums::VoiceAssistantRequestFlag value) {
|
||||
switch (value) {
|
||||
case enums::VOICE_ASSISTANT_REQUEST_NONE:
|
||||
return "VOICE_ASSISTANT_REQUEST_NONE";
|
||||
case enums::VOICE_ASSISTANT_REQUEST_USE_VAD:
|
||||
return "VOICE_ASSISTANT_REQUEST_USE_VAD";
|
||||
case enums::VOICE_ASSISTANT_REQUEST_USE_WAKE_WORD:
|
||||
return "VOICE_ASSISTANT_REQUEST_USE_WAKE_WORD";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
template<> const char *proto_enum_to_string<enums::VoiceAssistantEvent>(enums::VoiceAssistantEvent value) {
|
||||
switch (value) {
|
||||
case enums::VOICE_ASSISTANT_ERROR:
|
||||
@@ -428,6 +444,18 @@ template<> const char *proto_enum_to_string<enums::VoiceAssistantEvent>(enums::V
|
||||
return "VOICE_ASSISTANT_TTS_START";
|
||||
case enums::VOICE_ASSISTANT_TTS_END:
|
||||
return "VOICE_ASSISTANT_TTS_END";
|
||||
case enums::VOICE_ASSISTANT_WAKE_WORD_START:
|
||||
return "VOICE_ASSISTANT_WAKE_WORD_START";
|
||||
case enums::VOICE_ASSISTANT_WAKE_WORD_END:
|
||||
return "VOICE_ASSISTANT_WAKE_WORD_END";
|
||||
case enums::VOICE_ASSISTANT_STT_VAD_START:
|
||||
return "VOICE_ASSISTANT_STT_VAD_START";
|
||||
case enums::VOICE_ASSISTANT_STT_VAD_END:
|
||||
return "VOICE_ASSISTANT_STT_VAD_END";
|
||||
case enums::VOICE_ASSISTANT_TTS_STREAM_START:
|
||||
return "VOICE_ASSISTANT_TTS_STREAM_START";
|
||||
case enums::VOICE_ASSISTANT_TTS_STREAM_END:
|
||||
return "VOICE_ASSISTANT_TTS_STREAM_END";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -522,12 +550,12 @@ void HelloRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" api_version_major: ");
|
||||
sprintf(buffer, "%u", this->api_version_major);
|
||||
sprintf(buffer, "%" PRIu32, this->api_version_major);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" api_version_minor: ");
|
||||
sprintf(buffer, "%u", this->api_version_minor);
|
||||
sprintf(buffer, "%" PRIu32, this->api_version_minor);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -572,12 +600,12 @@ void HelloResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("HelloResponse {\n");
|
||||
out.append(" api_version_major: ");
|
||||
sprintf(buffer, "%u", this->api_version_major);
|
||||
sprintf(buffer, "%" PRIu32, this->api_version_major);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" api_version_minor: ");
|
||||
sprintf(buffer, "%u", this->api_version_minor);
|
||||
sprintf(buffer, "%" PRIu32, this->api_version_minor);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -783,17 +811,17 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" webserver_port: ");
|
||||
sprintf(buffer, "%u", this->webserver_port);
|
||||
sprintf(buffer, "%" PRIu32, this->webserver_port);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" legacy_bluetooth_proxy_version: ");
|
||||
sprintf(buffer, "%u", this->legacy_bluetooth_proxy_version);
|
||||
sprintf(buffer, "%" PRIu32, this->legacy_bluetooth_proxy_version);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" bluetooth_proxy_feature_flags: ");
|
||||
sprintf(buffer, "%u", this->bluetooth_proxy_feature_flags);
|
||||
sprintf(buffer, "%" PRIu32, this->bluetooth_proxy_feature_flags);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -806,7 +834,7 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" voice_assistant_version: ");
|
||||
sprintf(buffer, "%u", this->voice_assistant_version);
|
||||
sprintf(buffer, "%" PRIu32, this->voice_assistant_version);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -898,7 +926,7 @@ void ListEntitiesBinarySensorResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -966,7 +994,7 @@ void BinarySensorStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("BinarySensorStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1069,7 +1097,7 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1159,7 +1187,7 @@ void CoverStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("CoverStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1242,7 +1270,7 @@ void CoverCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("CoverCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1362,7 +1390,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1387,7 +1415,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" supported_speed_count: ");
|
||||
sprintf(buffer, "%d", this->supported_speed_count);
|
||||
sprintf(buffer, "%" PRId32, this->supported_speed_count);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1454,7 +1482,7 @@ void FanStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("FanStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1475,7 +1503,7 @@ void FanStateResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" speed_level: ");
|
||||
sprintf(buffer, "%d", this->speed_level);
|
||||
sprintf(buffer, "%" PRId32, this->speed_level);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -1555,7 +1583,7 @@ void FanCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("FanCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1596,7 +1624,7 @@ void FanCommandRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" speed_level: ");
|
||||
sprintf(buffer, "%d", this->speed_level);
|
||||
sprintf(buffer, "%" PRId32, this->speed_level);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -1710,7 +1738,7 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -1864,7 +1892,7 @@ void LightStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("LightStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2087,7 +2115,7 @@ void LightCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("LightCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2185,7 +2213,7 @@ void LightCommandRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" transition_length: ");
|
||||
sprintf(buffer, "%u", this->transition_length);
|
||||
sprintf(buffer, "%" PRIu32, this->transition_length);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2194,7 +2222,7 @@ void LightCommandRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" flash_length: ");
|
||||
sprintf(buffer, "%u", this->flash_length);
|
||||
sprintf(buffer, "%" PRIu32, this->flash_length);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2302,7 +2330,7 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2323,7 +2351,7 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" accuracy_decimals: ");
|
||||
sprintf(buffer, "%d", this->accuracy_decimals);
|
||||
sprintf(buffer, "%" PRId32, this->accuracy_decimals);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2387,7 +2415,7 @@ void SensorStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("SensorStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2476,7 +2504,7 @@ void ListEntitiesSwitchResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2539,7 +2567,7 @@ void SwitchStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("SwitchStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2578,7 +2606,7 @@ void SwitchCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("SwitchCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2652,7 +2680,7 @@ void ListEntitiesTextSensorResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -2718,7 +2746,7 @@ void TextSensorStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("TextSensorStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3025,7 +3053,7 @@ void GetTimeResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("GetTimeResponse {\n");
|
||||
out.append(" epoch_seconds: ");
|
||||
sprintf(buffer, "%u", this->epoch_seconds);
|
||||
sprintf(buffer, "%" PRIu32, this->epoch_seconds);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -3109,7 +3137,7 @@ void ListEntitiesServicesResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3203,7 +3231,7 @@ void ExecuteServiceArgument::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" legacy_int: ");
|
||||
sprintf(buffer, "%d", this->legacy_int);
|
||||
sprintf(buffer, "%" PRId32, this->legacy_int);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3217,7 +3245,7 @@ void ExecuteServiceArgument::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" int_: ");
|
||||
sprintf(buffer, "%d", this->int_);
|
||||
sprintf(buffer, "%" PRId32, this->int_);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3229,7 +3257,7 @@ void ExecuteServiceArgument::dump_to(std::string &out) const {
|
||||
|
||||
for (const auto &it : this->int_array) {
|
||||
out.append(" int_array: ");
|
||||
sprintf(buffer, "%d", it);
|
||||
sprintf(buffer, "%" PRId32, it);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
}
|
||||
@@ -3280,7 +3308,7 @@ void ExecuteServiceRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("ExecuteServiceRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3356,7 +3384,7 @@ void ListEntitiesCameraResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3422,7 +3450,7 @@ void CameraImageResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("CameraImageResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3614,7 +3642,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3802,7 +3830,7 @@ void ClimateStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("ClimateStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -3990,7 +4018,7 @@ void ClimateCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("ClimateCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4173,7 +4201,7 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4260,7 +4288,7 @@ void NumberStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("NumberStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4298,7 +4326,7 @@ void NumberCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("NumberCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4380,7 +4408,7 @@ void ListEntitiesSelectResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4452,7 +4480,7 @@ void SelectStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("SelectStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4495,7 +4523,7 @@ void SelectCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("SelectCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4589,7 +4617,7 @@ void ListEntitiesLockResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4660,7 +4688,7 @@ void LockStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("LockStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4715,7 +4743,7 @@ void LockCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("LockCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4802,7 +4830,7 @@ void ListEntitiesButtonResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4848,7 +4876,7 @@ void ButtonCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("ButtonCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -4923,7 +4951,7 @@ void ListEntitiesMediaPlayerResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -4992,7 +5020,7 @@ void MediaPlayerStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("MediaPlayerStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5071,7 +5099,7 @@ void MediaPlayerCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("MediaPlayerCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5120,7 +5148,7 @@ void SubscribeBluetoothLEAdvertisementsRequest::dump_to(std::string &out) const
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("SubscribeBluetoothLEAdvertisementsRequest {\n");
|
||||
out.append(" flags: ");
|
||||
sprintf(buffer, "%u", this->flags);
|
||||
sprintf(buffer, "%" PRIu32, this->flags);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5167,7 +5195,7 @@ void BluetoothServiceData::dump_to(std::string &out) const {
|
||||
|
||||
for (const auto &it : this->legacy_data) {
|
||||
out.append(" legacy_data: ");
|
||||
sprintf(buffer, "%u", it);
|
||||
sprintf(buffer, "%" PRIu32, it);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
}
|
||||
@@ -5247,7 +5275,7 @@ void BluetoothLEAdvertisementResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" rssi: ");
|
||||
sprintf(buffer, "%d", this->rssi);
|
||||
sprintf(buffer, "%" PRId32, this->rssi);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5270,7 +5298,7 @@ void BluetoothLEAdvertisementResponse::dump_to(std::string &out) const {
|
||||
}
|
||||
|
||||
out.append(" address_type: ");
|
||||
sprintf(buffer, "%u", this->address_type);
|
||||
sprintf(buffer, "%" PRIu32, this->address_type);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5320,12 +5348,12 @@ void BluetoothLERawAdvertisement::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" rssi: ");
|
||||
sprintf(buffer, "%d", this->rssi);
|
||||
sprintf(buffer, "%" PRId32, this->rssi);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" address_type: ");
|
||||
sprintf(buffer, "%u", this->address_type);
|
||||
sprintf(buffer, "%" PRIu32, this->address_type);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5408,7 +5436,7 @@ void BluetoothDeviceRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" address_type: ");
|
||||
sprintf(buffer, "%u", this->address_type);
|
||||
sprintf(buffer, "%" PRIu32, this->address_type);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5456,12 +5484,12 @@ void BluetoothDeviceConnectionResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" mtu: ");
|
||||
sprintf(buffer, "%u", this->mtu);
|
||||
sprintf(buffer, "%" PRIu32, this->mtu);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" error: ");
|
||||
sprintf(buffer, "%d", this->error);
|
||||
sprintf(buffer, "%" PRId32, this->error);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5521,7 +5549,7 @@ void BluetoothGATTDescriptor::dump_to(std::string &out) const {
|
||||
}
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5577,12 +5605,12 @@ void BluetoothGATTCharacteristic::dump_to(std::string &out) const {
|
||||
}
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" properties: ");
|
||||
sprintf(buffer, "%u", this->properties);
|
||||
sprintf(buffer, "%" PRIu32, this->properties);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5639,7 +5667,7 @@ void BluetoothGATTService::dump_to(std::string &out) const {
|
||||
}
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5746,7 +5774,7 @@ void BluetoothGATTReadRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5791,7 +5819,7 @@ void BluetoothGATTReadResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5845,7 +5873,7 @@ void BluetoothGATTWriteRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5887,7 +5915,7 @@ void BluetoothGATTReadDescriptorRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -5932,7 +5960,7 @@ void BluetoothGATTWriteDescriptorRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -5975,7 +6003,7 @@ void BluetoothGATTNotifyRequest::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -6024,7 +6052,7 @@ void BluetoothGATTNotifyDataResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -6063,12 +6091,12 @@ void BluetoothConnectionsFreeResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("BluetoothConnectionsFreeResponse {\n");
|
||||
out.append(" free: ");
|
||||
sprintf(buffer, "%u", this->free);
|
||||
sprintf(buffer, "%" PRIu32, this->free);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" limit: ");
|
||||
sprintf(buffer, "%u", this->limit);
|
||||
sprintf(buffer, "%" PRIu32, this->limit);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6107,12 +6135,12 @@ void BluetoothGATTErrorResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" error: ");
|
||||
sprintf(buffer, "%d", this->error);
|
||||
sprintf(buffer, "%" PRId32, this->error);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6146,7 +6174,7 @@ void BluetoothGATTWriteResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6180,7 +6208,7 @@ void BluetoothGATTNotifyResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" handle: ");
|
||||
sprintf(buffer, "%u", this->handle);
|
||||
sprintf(buffer, "%" PRIu32, this->handle);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6223,7 +6251,7 @@ void BluetoothDevicePairingResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" error: ");
|
||||
sprintf(buffer, "%d", this->error);
|
||||
sprintf(buffer, "%" PRId32, this->error);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6266,7 +6294,7 @@ void BluetoothDeviceUnpairingResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" error: ");
|
||||
sprintf(buffer, "%d", this->error);
|
||||
sprintf(buffer, "%" PRId32, this->error);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6315,7 +6343,7 @@ void BluetoothDeviceClearCacheResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" error: ");
|
||||
sprintf(buffer, "%d", this->error);
|
||||
sprintf(buffer, "%" PRId32, this->error);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
@@ -6342,6 +6370,56 @@ void SubscribeVoiceAssistantRequest::dump_to(std::string &out) const {
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
bool VoiceAssistantAudioSettings::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 1: {
|
||||
this->noise_suppression_level = value.as_uint32();
|
||||
return true;
|
||||
}
|
||||
case 2: {
|
||||
this->auto_gain = value.as_uint32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool VoiceAssistantAudioSettings::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
switch (field_id) {
|
||||
case 3: {
|
||||
this->volume_multiplier = value.as_float();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void VoiceAssistantAudioSettings::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_uint32(1, this->noise_suppression_level);
|
||||
buffer.encode_uint32(2, this->auto_gain);
|
||||
buffer.encode_float(3, this->volume_multiplier);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void VoiceAssistantAudioSettings::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("VoiceAssistantAudioSettings {\n");
|
||||
out.append(" noise_suppression_level: ");
|
||||
sprintf(buffer, "%" PRIu32, this->noise_suppression_level);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" auto_gain: ");
|
||||
sprintf(buffer, "%" PRIu32, this->auto_gain);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" volume_multiplier: ");
|
||||
sprintf(buffer, "%g", this->volume_multiplier);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
bool VoiceAssistantRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 1: {
|
||||
@@ -6349,7 +6427,7 @@ bool VoiceAssistantRequest::decode_varint(uint32_t field_id, ProtoVarInt value)
|
||||
return true;
|
||||
}
|
||||
case 3: {
|
||||
this->use_vad = value.as_bool();
|
||||
this->flags = value.as_uint32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
@@ -6362,6 +6440,10 @@ bool VoiceAssistantRequest::decode_length(uint32_t field_id, ProtoLengthDelimite
|
||||
this->conversation_id = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 4: {
|
||||
this->audio_settings = value.as_message<VoiceAssistantAudioSettings>();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -6369,7 +6451,8 @@ bool VoiceAssistantRequest::decode_length(uint32_t field_id, ProtoLengthDelimite
|
||||
void VoiceAssistantRequest::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_bool(1, this->start);
|
||||
buffer.encode_string(2, this->conversation_id);
|
||||
buffer.encode_bool(3, this->use_vad);
|
||||
buffer.encode_uint32(3, this->flags);
|
||||
buffer.encode_message<VoiceAssistantAudioSettings>(4, this->audio_settings);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void VoiceAssistantRequest::dump_to(std::string &out) const {
|
||||
@@ -6383,8 +6466,13 @@ void VoiceAssistantRequest::dump_to(std::string &out) const {
|
||||
out.append("'").append(this->conversation_id).append("'");
|
||||
out.append("\n");
|
||||
|
||||
out.append(" use_vad: ");
|
||||
out.append(YESNO(this->use_vad));
|
||||
out.append(" flags: ");
|
||||
sprintf(buffer, "%" PRIu32, this->flags);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" audio_settings: ");
|
||||
this->audio_settings.dump_to(out);
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
@@ -6412,7 +6500,7 @@ void VoiceAssistantResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("VoiceAssistantResponse {\n");
|
||||
out.append(" port: ");
|
||||
sprintf(buffer, "%u", this->port);
|
||||
sprintf(buffer, "%" PRIu32, this->port);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -6575,7 +6663,7 @@ void ListEntitiesAlarmControlPanelResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -6600,7 +6688,7 @@ void ListEntitiesAlarmControlPanelResponse::dump_to(std::string &out) const {
|
||||
out.append("\n");
|
||||
|
||||
out.append(" supported_features: ");
|
||||
sprintf(buffer, "%u", this->supported_features);
|
||||
sprintf(buffer, "%" PRIu32, this->supported_features);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -6643,7 +6731,7 @@ void AlarmControlPanelStateResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("AlarmControlPanelStateResponse {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
@@ -6693,7 +6781,7 @@ void AlarmControlPanelCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("AlarmControlPanelCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
sprintf(buffer, "%" PRIu32, this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
|
@@ -165,6 +165,11 @@ enum BluetoothDeviceRequestType : uint32_t {
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5,
|
||||
BLUETOOTH_DEVICE_REQUEST_TYPE_CLEAR_CACHE = 6,
|
||||
};
|
||||
enum VoiceAssistantRequestFlag : uint32_t {
|
||||
VOICE_ASSISTANT_REQUEST_NONE = 0,
|
||||
VOICE_ASSISTANT_REQUEST_USE_VAD = 1,
|
||||
VOICE_ASSISTANT_REQUEST_USE_WAKE_WORD = 2,
|
||||
};
|
||||
enum VoiceAssistantEvent : uint32_t {
|
||||
VOICE_ASSISTANT_ERROR = 0,
|
||||
VOICE_ASSISTANT_RUN_START = 1,
|
||||
@@ -175,6 +180,12 @@ enum VoiceAssistantEvent : uint32_t {
|
||||
VOICE_ASSISTANT_INTENT_END = 6,
|
||||
VOICE_ASSISTANT_TTS_START = 7,
|
||||
VOICE_ASSISTANT_TTS_END = 8,
|
||||
VOICE_ASSISTANT_WAKE_WORD_START = 9,
|
||||
VOICE_ASSISTANT_WAKE_WORD_END = 10,
|
||||
VOICE_ASSISTANT_STT_VAD_START = 11,
|
||||
VOICE_ASSISTANT_STT_VAD_END = 12,
|
||||
VOICE_ASSISTANT_TTS_STREAM_START = 98,
|
||||
VOICE_ASSISTANT_TTS_STREAM_END = 99,
|
||||
};
|
||||
enum AlarmControlPanelState : uint32_t {
|
||||
ALARM_STATE_DISARMED = 0,
|
||||
@@ -1651,11 +1662,26 @@ class SubscribeVoiceAssistantRequest : public ProtoMessage {
|
||||
protected:
|
||||
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
||||
};
|
||||
class VoiceAssistantAudioSettings : public ProtoMessage {
|
||||
public:
|
||||
uint32_t noise_suppression_level{0};
|
||||
uint32_t auto_gain{0};
|
||||
float volume_multiplier{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
|
||||
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
||||
};
|
||||
class VoiceAssistantRequest : public ProtoMessage {
|
||||
public:
|
||||
bool start{false};
|
||||
std::string conversation_id{};
|
||||
bool use_vad{false};
|
||||
uint32_t flags{0};
|
||||
VoiceAssistantAudioSettings audio_settings{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
@@ -1,13 +1,13 @@
|
||||
#include "api_server.h"
|
||||
#include <cerrno>
|
||||
#include "api_connection.h"
|
||||
#include "esphome/components/network/util.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/util.h"
|
||||
#include "esphome/core/version.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/network/util.h"
|
||||
#include <cerrno>
|
||||
|
||||
#ifdef USE_LOGGER
|
||||
#include "esphome/components/logger/logger.h"
|
||||
@@ -323,16 +323,24 @@ void APIServer::on_shutdown() {
|
||||
}
|
||||
|
||||
#ifdef USE_VOICE_ASSISTANT
|
||||
bool APIServer::start_voice_assistant(const std::string &conversation_id, bool use_vad) {
|
||||
bool APIServer::start_voice_assistant(const std::string &conversation_id, uint32_t flags,
|
||||
const api::VoiceAssistantAudioSettings &audio_settings) {
|
||||
VoiceAssistantRequest msg;
|
||||
msg.start = true;
|
||||
msg.conversation_id = conversation_id;
|
||||
msg.flags = flags;
|
||||
msg.audio_settings = audio_settings;
|
||||
for (auto &c : this->clients_) {
|
||||
if (c->request_voice_assistant(true, conversation_id, use_vad))
|
||||
if (c->request_voice_assistant(msg))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void APIServer::stop_voice_assistant() {
|
||||
VoiceAssistantRequest msg;
|
||||
msg.start = false;
|
||||
for (auto &c : this->clients_) {
|
||||
if (c->request_voice_assistant(false, "", false))
|
||||
if (c->request_voice_assistant(msg))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "api_noise_context.h"
|
||||
#include "api_pb2.h"
|
||||
#include "api_pb2_service.h"
|
||||
#include "esphome/components/socket/socket.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/controller.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/components/socket/socket.h"
|
||||
#include "api_pb2.h"
|
||||
#include "api_pb2_service.h"
|
||||
#include "list_entities.h"
|
||||
#include "subscribe_state.h"
|
||||
#include "user_services.h"
|
||||
#include "api_noise_context.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -81,7 +81,8 @@ class APIServer : public Component, public Controller {
|
||||
#endif
|
||||
|
||||
#ifdef USE_VOICE_ASSISTANT
|
||||
bool start_voice_assistant(const std::string &conversation_id, bool use_vad);
|
||||
bool start_voice_assistant(const std::string &conversation_id, uint32_t flags,
|
||||
const api::VoiceAssistantAudioSettings &audio_settings);
|
||||
void stop_voice_assistant();
|
||||
#endif
|
||||
|
||||
|
@@ -2,14 +2,17 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import (
|
||||
CONF_CAPACITANCE,
|
||||
CONF_DIV_RATIO,
|
||||
CONF_INDOOR,
|
||||
CONF_WATCHDOG_THRESHOLD,
|
||||
CONF_NOISE_LEVEL,
|
||||
CONF_SPIKE_REJECTION,
|
||||
CONF_IRQ_PIN,
|
||||
CONF_LIGHTNING_THRESHOLD,
|
||||
CONF_MASK_DISTURBER,
|
||||
CONF_DIV_RATIO,
|
||||
CONF_CAPACITANCE,
|
||||
CONF_CALIBRATION,
|
||||
CONF_TUNE_ANTENNA,
|
||||
CONF_NOISE_LEVEL,
|
||||
CONF_SPIKE_REJECTION,
|
||||
CONF_WATCHDOG_THRESHOLD,
|
||||
)
|
||||
|
||||
MULTI_CONF = True
|
||||
@@ -19,7 +22,6 @@ CONF_AS3935_ID = "as3935_id"
|
||||
as3935_ns = cg.esphome_ns.namespace("as3935")
|
||||
AS3935 = as3935_ns.class_("AS3935Component", cg.Component)
|
||||
|
||||
CONF_IRQ_PIN = "irq_pin"
|
||||
AS3935_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AS3935),
|
||||
@@ -34,6 +36,8 @@ AS3935_SCHEMA = cv.Schema(
|
||||
cv.Optional(CONF_MASK_DISTURBER, default=False): cv.boolean,
|
||||
cv.Optional(CONF_DIV_RATIO, default=0): cv.one_of(0, 16, 32, 64, 128, int=True),
|
||||
cv.Optional(CONF_CAPACITANCE, default=0): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_TUNE_ANTENNA, default=False): cv.boolean,
|
||||
cv.Optional(CONF_CALIBRATION, default=True): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -51,3 +55,5 @@ async def setup_as3935(var, config):
|
||||
cg.add(var.set_mask_disturber(config[CONF_MASK_DISTURBER]))
|
||||
cg.add(var.set_div_ratio(config[CONF_DIV_RATIO]))
|
||||
cg.add(var.set_capacitance(config[CONF_CAPACITANCE]))
|
||||
cg.add(var.set_tune_antenna(config[CONF_TUNE_ANTENNA]))
|
||||
cg.add(var.set_calibration(config[CONF_CALIBRATION]))
|
||||
|
@@ -21,6 +21,14 @@ void AS3935Component::setup() {
|
||||
this->write_mask_disturber(this->mask_disturber_);
|
||||
this->write_div_ratio(this->div_ratio_);
|
||||
this->write_capacitance(this->capacitance_);
|
||||
|
||||
// Handle setting up tuning or auto-calibration
|
||||
if (this->tune_antenna_) {
|
||||
ESP_LOGCONFIG(TAG, " Antenna tuning: ENABLED - lightning detection will not function in this mode");
|
||||
this->tune_antenna();
|
||||
} else if (this->calibration_) {
|
||||
this->calibrate_oscillator();
|
||||
}
|
||||
}
|
||||
|
||||
void AS3935Component::dump_config() {
|
||||
@@ -227,6 +235,87 @@ uint32_t AS3935Component::get_lightning_energy_() {
|
||||
return pure_light;
|
||||
}
|
||||
|
||||
// REG0x03, bit [7:6], manufacturer default: 0 (16 division ratio).
|
||||
// This function returns the current division ratio of the resonance frequency.
|
||||
// The antenna resonance frequency should be within 3.5 percent of 500kHz, and
|
||||
// so when modifying the resonance frequency with the internal capacitors
|
||||
// (tuneCap()) it's important to keep in mind that the displayed frequency on
|
||||
// the IRQ pin is divided by this number.
|
||||
uint8_t AS3935Component::read_div_ratio() {
|
||||
ESP_LOGV(TAG, "Calling read_div_ratio");
|
||||
uint8_t reg_val = this->read_register_(INT_MASK_ANT, DIV_MASK);
|
||||
reg_val >>= 6; // Front of the line.
|
||||
|
||||
if (reg_val == 0) {
|
||||
return 16;
|
||||
} else if (reg_val == 1) {
|
||||
return 32;
|
||||
} else if (reg_val == 2) {
|
||||
return 64;
|
||||
} else if (reg_val == 3) {
|
||||
return 128;
|
||||
}
|
||||
ESP_LOGW(TAG, "Unknown response received for div_ratio");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t AS3935Component::read_capacitance() {
|
||||
ESP_LOGV(TAG, "Calling read_capacitance");
|
||||
uint8_t reg_val = this->read_register_(FREQ_DISP_IRQ, CAP_MASK) * 8;
|
||||
return (reg_val);
|
||||
}
|
||||
|
||||
// REG0x08, bits [5,6,7], manufacturer default: 0.
|
||||
// This will send the frequency of the oscillators to the IRQ pin.
|
||||
// _osc 1, bit[5] = TRCO - System RCO at 32.768kHz
|
||||
// _osc 2, bit[6] = SRCO - Timer RCO Oscillators 1.1MHz
|
||||
// _osc 3, bit[7] = LCO - Frequency of the Antenna
|
||||
void AS3935Component::display_oscillator(bool state, uint8_t osc) {
|
||||
if ((osc < 1) || (osc > 3))
|
||||
return;
|
||||
|
||||
this->write_register(FREQ_DISP_IRQ, OSC_MASK, state, 4 + osc);
|
||||
}
|
||||
|
||||
// REG0x3D, bits[7:0]
|
||||
// This function calibrates both internal oscillators The oscillators are tuned
|
||||
// based on the resonance frequency of the antenna and so it should be trimmed
|
||||
// before the calibration is done.
|
||||
bool AS3935Component::calibrate_oscillator() {
|
||||
ESP_LOGI(TAG, "Starting oscillators calibration...");
|
||||
this->write_register(CALIB_RCO, WIPE_ALL, DIRECT_COMMAND, 0); // Send command to calibrate the oscillators
|
||||
|
||||
this->display_oscillator(true, 2);
|
||||
delay(2); // Give time for the internal oscillators to start up.
|
||||
this->display_oscillator(false, 2);
|
||||
|
||||
// Check it they were calibrated successfully.
|
||||
uint8_t reg_val_srco = this->read_register_(CALIB_SRCO, CALIB_MASK_NOK);
|
||||
uint8_t reg_val_trco = this->read_register_(CALIB_TRCO, CALIB_MASK_NOK);
|
||||
|
||||
// reg_val_srco &= CALIB_MASK;
|
||||
// reg_val_srco >>= 6;
|
||||
// reg_val_trco &= CALIB_MASK;
|
||||
// reg_val_trco >>= 6;
|
||||
if (!reg_val_srco && !reg_val_trco) { // Zero upon success
|
||||
ESP_LOGI(TAG, "Calibration was succesful");
|
||||
return true;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Calibration was NOT succesful");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AS3935Component::tune_antenna() {
|
||||
ESP_LOGI(TAG, "Starting antenna tuning...");
|
||||
uint8_t div_ratio = this->read_div_ratio();
|
||||
uint8_t tune_val = this->read_capacitance();
|
||||
ESP_LOGI(TAG, "Division Ratio is set to: %d", div_ratio);
|
||||
ESP_LOGI(TAG, "Internal Capacitor is set to: %d", tune_val);
|
||||
ESP_LOGI(TAG, "Displaying oscillator on INT pin. Measure its frequency - multiply value by Division Ratio");
|
||||
this->display_oscillator(true, ANTFREQ);
|
||||
}
|
||||
|
||||
uint8_t AS3935Component::read_register_(uint8_t reg, uint8_t mask) {
|
||||
uint8_t value = this->read_register(reg);
|
||||
value &= (~mask);
|
||||
|
@@ -13,6 +13,9 @@
|
||||
namespace esphome {
|
||||
namespace as3935 {
|
||||
|
||||
static const uint8_t DIRECT_COMMAND = 0x96;
|
||||
static const uint8_t ANTFREQ = 3;
|
||||
|
||||
enum AS3935RegisterNames {
|
||||
AFE_GAIN = 0x00,
|
||||
THRESHOLD,
|
||||
@@ -30,6 +33,7 @@ enum AS3935RegisterNames {
|
||||
};
|
||||
|
||||
enum AS3935RegisterMasks {
|
||||
WIPE_ALL = 0x0,
|
||||
GAIN_MASK = 0x3E,
|
||||
SPIKE_MASK = 0xF,
|
||||
IO_MASK = 0xC1,
|
||||
@@ -44,6 +48,7 @@ enum AS3935RegisterMasks {
|
||||
NOISE_FLOOR_MASK = 0x70,
|
||||
OSC_MASK = 0xE0,
|
||||
CALIB_MASK = 0x7F,
|
||||
CALIB_MASK_NOK = 0xBF,
|
||||
DIV_MASK = 0x3F
|
||||
};
|
||||
|
||||
@@ -90,6 +95,13 @@ class AS3935Component : public Component {
|
||||
void write_div_ratio(uint8_t div_ratio);
|
||||
void set_capacitance(uint8_t capacitance) { capacitance_ = capacitance; }
|
||||
void write_capacitance(uint8_t capacitance);
|
||||
uint8_t read_div_ratio();
|
||||
uint8_t read_capacitance();
|
||||
bool calibrate_oscillator();
|
||||
void display_oscillator(bool state, uint8_t osc);
|
||||
void tune_antenna();
|
||||
void set_tune_antenna(bool tune_antenna) { tune_antenna_ = tune_antenna; }
|
||||
void set_calibration(bool calibration) { calibration_ = calibration; }
|
||||
|
||||
protected:
|
||||
uint8_t read_interrupt_register_();
|
||||
@@ -112,6 +124,8 @@ class AS3935Component : public Component {
|
||||
bool mask_disturber_;
|
||||
uint8_t div_ratio_;
|
||||
uint8_t capacitance_;
|
||||
bool tune_antenna_;
|
||||
bool calibration_;
|
||||
};
|
||||
|
||||
} // namespace as3935
|
||||
|
@@ -31,12 +31,10 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
async def to_code(config):
|
||||
hub = await cg.get_variable(config[CONF_AS3935_ID])
|
||||
|
||||
if CONF_DISTANCE in config:
|
||||
conf = config[CONF_DISTANCE]
|
||||
distance_sensor = await sensor.new_sensor(conf)
|
||||
cg.add(hub.set_distance_sensor(distance_sensor))
|
||||
if distance_config := config.get(CONF_DISTANCE):
|
||||
sens = await sensor.new_sensor(distance_config)
|
||||
cg.add(hub.set_distance_sensor(sens))
|
||||
|
||||
if CONF_LIGHTNING_ENERGY in config:
|
||||
conf = config[CONF_LIGHTNING_ENERGY]
|
||||
lightning_energy_sensor = await sensor.new_sensor(conf)
|
||||
cg.add(hub.set_energy_sensor(lightning_energy_sensor))
|
||||
if lightning_energy_config := config.get(CONF_LIGHTNING_ENERGY):
|
||||
sens = await sensor.new_sensor(lightning_energy_config)
|
||||
cg.add(hub.set_energy_sensor(sens))
|
||||
|
@@ -107,6 +107,6 @@ async def to_code(config):
|
||||
cg.add(var.set_astep(config[CONF_ASTEP]))
|
||||
|
||||
for conf_id, set_sensor_func in SENSORS.items():
|
||||
if conf_id in config:
|
||||
sens = await sensor.new_sensor(config[conf_id])
|
||||
if sens_config := config.get(conf_id):
|
||||
sens = await sensor.new_sensor(sens_config)
|
||||
cg.add(getattr(var, set_sensor_func)(sens))
|
||||
|
@@ -2,21 +2,27 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.const import (
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_BK72XX,
|
||||
PLATFORM_RTL87XX,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema({}),
|
||||
cv.only_with_arduino,
|
||||
cv.only_on(["esp32", "esp8266"]),
|
||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
|
||||
)
|
||||
|
||||
|
||||
@coroutine_with_priority(200.0)
|
||||
async def to_code(config):
|
||||
if CORE.is_esp32:
|
||||
if CORE.is_esp32 or CORE.is_libretiny:
|
||||
# https://github.com/esphome/AsyncTCP/blob/master/library.json
|
||||
cg.add_library("esphome/AsyncTCP-esphome", "1.2.2")
|
||||
cg.add_library("esphome/AsyncTCP-esphome", "2.0.1")
|
||||
elif CORE.is_esp8266:
|
||||
# https://github.com/esphome/ESPAsyncTCP
|
||||
cg.add_library("esphome/ESPAsyncTCP-esphome", "1.2.3")
|
||||
cg.add_library("esphome/ESPAsyncTCP-esphome", "2.0.0")
|
||||
|
@@ -83,18 +83,18 @@ async def to_code(config):
|
||||
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature(sens))
|
||||
if CONF_HUMIDITY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_HUMIDITY])
|
||||
if humidity_config := config.get(CONF_HUMIDITY):
|
||||
sens = await sensor.new_sensor(humidity_config)
|
||||
cg.add(var.set_humidity(sens))
|
||||
if CONF_BATTERY_LEVEL in config:
|
||||
sens = await sensor.new_sensor(config[CONF_BATTERY_LEVEL])
|
||||
if battery_level_config := config.get(CONF_BATTERY_LEVEL):
|
||||
sens = await sensor.new_sensor(battery_level_config)
|
||||
cg.add(var.set_battery_level(sens))
|
||||
if CONF_BATTERY_VOLTAGE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_BATTERY_VOLTAGE])
|
||||
if battery_voltage_config := config.get(CONF_BATTERY_VOLTAGE):
|
||||
sens = await sensor.new_sensor(battery_voltage_config)
|
||||
cg.add(var.set_battery_voltage(sens))
|
||||
if CONF_SIGNAL_STRENGTH in config:
|
||||
sens = await sensor.new_sensor(config[CONF_SIGNAL_STRENGTH])
|
||||
if signal_strength_config := config.get(CONF_SIGNAL_STRENGTH):
|
||||
sens = await sensor.new_sensor(signal_strength_config)
|
||||
cg.add(var.set_signal_strength(sens))
|
||||
|
@@ -124,29 +124,29 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await spi.register_spi_device(var, config)
|
||||
|
||||
if CONF_VOLTAGE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_VOLTAGE])
|
||||
if voltage_config := config.get(CONF_VOLTAGE):
|
||||
sens = await sensor.new_sensor(voltage_config)
|
||||
cg.add(var.set_voltage_sensor(sens))
|
||||
if CONF_CURRENT in config:
|
||||
sens = await sensor.new_sensor(config[CONF_CURRENT])
|
||||
if current_config := config.get(CONF_CURRENT):
|
||||
sens = await sensor.new_sensor(current_config)
|
||||
cg.add(var.set_current_sensor(sens))
|
||||
if CONF_POWER in config:
|
||||
sens = await sensor.new_sensor(config[CONF_POWER])
|
||||
if power_config := config.get(CONF_POWER):
|
||||
sens = await sensor.new_sensor(power_config)
|
||||
cg.add(var.set_power_sensor(sens))
|
||||
if CONF_REACTIVE_POWER in config:
|
||||
sens = await sensor.new_sensor(config[CONF_REACTIVE_POWER])
|
||||
if reactive_power_config := config.get(CONF_REACTIVE_POWER):
|
||||
sens = await sensor.new_sensor(reactive_power_config)
|
||||
cg.add(var.set_reactive_power_sensor(sens))
|
||||
if CONF_POWER_FACTOR in config:
|
||||
sens = await sensor.new_sensor(config[CONF_POWER_FACTOR])
|
||||
if power_factor_config := config.get(CONF_POWER_FACTOR):
|
||||
sens = await sensor.new_sensor(power_factor_config)
|
||||
cg.add(var.set_power_factor_sensor(sens))
|
||||
if CONF_FORWARD_ACTIVE_ENERGY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_FORWARD_ACTIVE_ENERGY])
|
||||
if forward_active_energy_config := config.get(CONF_FORWARD_ACTIVE_ENERGY):
|
||||
sens = await sensor.new_sensor(forward_active_energy_config)
|
||||
cg.add(var.set_forward_active_energy_sensor(sens))
|
||||
if CONF_REVERSE_ACTIVE_ENERGY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_REVERSE_ACTIVE_ENERGY])
|
||||
if reverse_active_energy_config := config.get(CONF_REVERSE_ACTIVE_ENERGY):
|
||||
sens = await sensor.new_sensor(reverse_active_energy_config)
|
||||
cg.add(var.set_reverse_active_energy_sensor(sens))
|
||||
if CONF_FREQUENCY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_FREQUENCY])
|
||||
if frequency_config := config.get(CONF_FREQUENCY):
|
||||
sens = await sensor.new_sensor(frequency_config)
|
||||
cg.add(var.set_freq_sensor(sens))
|
||||
cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY]))
|
||||
cg.add(var.set_meter_constant(config[CONF_METER_CONSTANT]))
|
||||
|
@@ -6,6 +6,9 @@ from esphome.const import (
|
||||
CONF_REACTIVE_POWER,
|
||||
CONF_VOLTAGE,
|
||||
CONF_CURRENT,
|
||||
CONF_PHASE_A,
|
||||
CONF_PHASE_B,
|
||||
CONF_PHASE_C,
|
||||
CONF_POWER,
|
||||
CONF_POWER_FACTOR,
|
||||
CONF_FREQUENCY,
|
||||
@@ -31,10 +34,6 @@ from esphome.const import (
|
||||
UNIT_WATT_HOURS,
|
||||
)
|
||||
|
||||
CONF_PHASE_A = "phase_a"
|
||||
CONF_PHASE_B = "phase_b"
|
||||
CONF_PHASE_C = "phase_c"
|
||||
|
||||
CONF_LINE_FREQUENCY = "line_frequency"
|
||||
CONF_CHIP_TEMPERATURE = "chip_temperature"
|
||||
CONF_GAIN_PGA = "gain_pga"
|
||||
@@ -151,33 +150,35 @@ async def to_code(config):
|
||||
conf = config[phase]
|
||||
cg.add(var.set_volt_gain(i, conf[CONF_GAIN_VOLTAGE]))
|
||||
cg.add(var.set_ct_gain(i, conf[CONF_GAIN_CT]))
|
||||
if CONF_VOLTAGE in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_VOLTAGE])
|
||||
if voltage_config := conf.get(CONF_VOLTAGE):
|
||||
sens = await sensor.new_sensor(voltage_config)
|
||||
cg.add(var.set_voltage_sensor(i, sens))
|
||||
if CONF_CURRENT in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_CURRENT])
|
||||
if current_config := conf.get(CONF_CURRENT):
|
||||
sens = await sensor.new_sensor(current_config)
|
||||
cg.add(var.set_current_sensor(i, sens))
|
||||
if CONF_POWER in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_POWER])
|
||||
if power_config := conf.get(CONF_POWER):
|
||||
sens = await sensor.new_sensor(power_config)
|
||||
cg.add(var.set_power_sensor(i, sens))
|
||||
if CONF_REACTIVE_POWER in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_REACTIVE_POWER])
|
||||
if reactive_power_config := conf.get(CONF_REACTIVE_POWER):
|
||||
sens = await sensor.new_sensor(reactive_power_config)
|
||||
cg.add(var.set_reactive_power_sensor(i, sens))
|
||||
if CONF_POWER_FACTOR in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_POWER_FACTOR])
|
||||
if power_factor_config := conf.get(CONF_POWER_FACTOR):
|
||||
sens = await sensor.new_sensor(power_factor_config)
|
||||
cg.add(var.set_power_factor_sensor(i, sens))
|
||||
if CONF_FORWARD_ACTIVE_ENERGY in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_FORWARD_ACTIVE_ENERGY])
|
||||
if forward_active_energy_config := conf.get(CONF_FORWARD_ACTIVE_ENERGY):
|
||||
sens = await sensor.new_sensor(forward_active_energy_config)
|
||||
cg.add(var.set_forward_active_energy_sensor(i, sens))
|
||||
if CONF_REVERSE_ACTIVE_ENERGY in conf:
|
||||
sens = await sensor.new_sensor(conf[CONF_REVERSE_ACTIVE_ENERGY])
|
||||
if reverse_active_energy_config := conf.get(CONF_REVERSE_ACTIVE_ENERGY):
|
||||
sens = await sensor.new_sensor(reverse_active_energy_config)
|
||||
cg.add(var.set_reverse_active_energy_sensor(i, sens))
|
||||
if CONF_FREQUENCY in config:
|
||||
sens = await sensor.new_sensor(config[CONF_FREQUENCY])
|
||||
|
||||
if frequency_config := config.get(CONF_FREQUENCY):
|
||||
sens = await sensor.new_sensor(frequency_config)
|
||||
cg.add(var.set_freq_sensor(sens))
|
||||
if CONF_CHIP_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_CHIP_TEMPERATURE])
|
||||
if chip_temperature_config := config.get(CONF_CHIP_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(chip_temperature_config)
|
||||
cg.add(var.set_chip_temperature_sensor(sens))
|
||||
|
||||
cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY]))
|
||||
cg.add(var.set_current_phases(config[CONF_CURRENT_PHASES]))
|
||||
cg.add(var.set_pga_gain(config[CONF_GAIN_PGA]))
|
||||
|
@@ -87,6 +87,6 @@ async def to_code(config):
|
||||
(CONF_MOISTURE, var.set_soil_moisture),
|
||||
(CONF_ILLUMINANCE, var.set_illuminance),
|
||||
]:
|
||||
if config_key in config:
|
||||
sens = await sensor.new_sensor(config[config_key])
|
||||
if sensor_config := config.get(config_key):
|
||||
sens = await sensor.new_sensor(sensor_config)
|
||||
cg.add(setter(sens))
|
||||
|
@@ -57,19 +57,18 @@ async def to_code(config):
|
||||
var.get_idle_trigger(), [], config[CONF_IDLE_ACTION]
|
||||
)
|
||||
|
||||
if CONF_COOL_ACTION in config:
|
||||
if cool_action_config := config.get(CONF_COOL_ACTION):
|
||||
await automation.build_automation(
|
||||
var.get_cool_trigger(), [], config[CONF_COOL_ACTION]
|
||||
var.get_cool_trigger(), [], cool_action_config
|
||||
)
|
||||
cg.add(var.set_supports_cool(True))
|
||||
if CONF_HEAT_ACTION in config:
|
||||
if heat_action_config := config.get(CONF_HEAT_ACTION):
|
||||
await automation.build_automation(
|
||||
var.get_heat_trigger(), [], config[CONF_HEAT_ACTION]
|
||||
var.get_heat_trigger(), [], heat_action_config
|
||||
)
|
||||
cg.add(var.set_supports_heat(True))
|
||||
|
||||
if CONF_AWAY_CONFIG in config:
|
||||
away = config[CONF_AWAY_CONFIG]
|
||||
if away := config.get(CONF_AWAY_CONFIG):
|
||||
away_config = BangBangClimateTargetTempConfig(
|
||||
away[CONF_DEFAULT_TARGET_TEMPERATURE_LOW],
|
||||
away[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH],
|
||||
|
@@ -45,8 +45,8 @@ async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await ble_client.register_ble_node(var, config)
|
||||
if CONF_TIME_ID in config:
|
||||
time_ = await cg.get_variable(config[CONF_TIME_ID])
|
||||
if time_id := config.get(CONF_TIME_ID):
|
||||
time_ = await cg.get_variable(time_id)
|
||||
cg.add(var.set_time_id(time_))
|
||||
if CONF_RECEIVE_TIMEOUT in config:
|
||||
cg.add(var.set_status_timeout(config[CONF_RECEIVE_TIMEOUT]))
|
||||
if (receive_timeout := config.get(CONF_RECEIVE_TIMEOUT)) is not None:
|
||||
cg.add(var.set_status_timeout(receive_timeout))
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "bedjet_hub.h"
|
||||
#include "bedjet_child.h"
|
||||
#include "bedjet_const.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
namespace bedjet {
|
||||
@@ -373,7 +374,7 @@ void BedJetHub::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
|
||||
if (this->last_notify_ == 0 || delta > MIN_NOTIFY_THROTTLE || this->force_refresh_) {
|
||||
// Set reentrant flag to prevent processing multiple packets.
|
||||
this->processing_ = true;
|
||||
ESP_LOGVV(TAG, "[%s] Decoding packet: last=%d, delta=%d, force=%s", this->get_name().c_str(),
|
||||
ESP_LOGVV(TAG, "[%s] Decoding packet: last=%" PRId32 ", delta=%" PRId32 ", force=%s", this->get_name().c_str(),
|
||||
this->last_notify_, delta, this->force_refresh_ ? "y" : "n");
|
||||
bool needs_extra = this->codec_->decode_notify(param->notify.value, param->notify.value_len);
|
||||
|
||||
@@ -523,11 +524,11 @@ void BedJetHub::dispatch_status_() {
|
||||
|
||||
ESP_LOGI(TAG, "[%s] Still waiting for first GATT notify event.", this->get_name().c_str());
|
||||
} else if (diff > NOTIFY_WARN_THRESHOLD) {
|
||||
ESP_LOGW(TAG, "[%s] Last GATT notify was %d seconds ago.", this->get_name().c_str(), diff / 1000);
|
||||
ESP_LOGW(TAG, "[%s] Last GATT notify was %" PRId32 " seconds ago.", this->get_name().c_str(), diff / 1000);
|
||||
}
|
||||
|
||||
if (this->timeout_ > 0 && diff > this->timeout_ && this->parent()->enabled) {
|
||||
ESP_LOGW(TAG, "[%s] Timed out after %d sec. Retrying...", this->get_name().c_str(), this->timeout_);
|
||||
ESP_LOGW(TAG, "[%s] Timed out after %" PRId32 " sec. Retrying...", this->get_name().c_str(), this->timeout_);
|
||||
// set_enabled(false) will only close the connection if state != IDLE.
|
||||
this->parent()->set_state(espbt::ClientState::CONNECTING);
|
||||
this->parent()->set_enabled(false);
|
||||
|
@@ -29,10 +29,10 @@ async def to_code(config):
|
||||
output_ = await cg.get_variable(config[CONF_OUTPUT])
|
||||
cg.add(var.set_output(output_))
|
||||
|
||||
if CONF_OSCILLATION_OUTPUT in config:
|
||||
oscillation_output = await cg.get_variable(config[CONF_OSCILLATION_OUTPUT])
|
||||
if oscillation_output_id := config.get(CONF_OSCILLATION_OUTPUT):
|
||||
oscillation_output = await cg.get_variable(oscillation_output_id)
|
||||
cg.add(var.set_oscillating(oscillation_output))
|
||||
|
||||
if CONF_DIRECTION_OUTPUT in config:
|
||||
direction_output = await cg.get_variable(config[CONF_DIRECTION_OUTPUT])
|
||||
if direction_output_id := config.get(CONF_DIRECTION_OUTPUT):
|
||||
direction_output = await cg.get_variable(direction_output_id)
|
||||
cg.add(var.set_direction(direction_output))
|
||||
|
@@ -467,14 +467,14 @@ def binary_sensor_schema(
|
||||
async def setup_binary_sensor_core_(var, config):
|
||||
await setup_entity(var, config)
|
||||
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||
if CONF_PUBLISH_INITIAL_STATE in config:
|
||||
cg.add(var.set_publish_initial_state(config[CONF_PUBLISH_INITIAL_STATE]))
|
||||
if CONF_INVERTED in config:
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
if CONF_FILTERS in config:
|
||||
filters = await cg.build_registry_list(FILTER_REGISTRY, config[CONF_FILTERS])
|
||||
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
|
||||
cg.add(var.set_device_class(device_class))
|
||||
if publish_initial_state := config.get(CONF_PUBLISH_INITIAL_STATE):
|
||||
cg.add(var.set_publish_initial_state(publish_initial_state))
|
||||
if inverted := config.get(CONF_INVERTED):
|
||||
cg.add(var.set_inverted(inverted))
|
||||
if filters_config := config.get(CONF_FILTERS):
|
||||
filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
|
||||
cg.add(var.add_filters(filters))
|
||||
|
||||
for conf in config.get(CONF_ON_PRESS, []):
|
||||
@@ -518,8 +518,8 @@ async def setup_binary_sensor_core_(var, config):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [(bool, "x")], conf)
|
||||
|
||||
if CONF_MQTT_ID in config:
|
||||
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
||||
if mqtt_id := config.get(CONF_MQTT_ID):
|
||||
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
||||
await mqtt.register_mqtt_component(mqtt_, config)
|
||||
|
||||
|
||||
|
51
esphome/components/bk72xx/__init__.py
Normal file
51
esphome/components/bk72xx/__init__.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# This file was auto-generated by libretiny/generate_components.py
|
||||
# Do not modify its contents.
|
||||
# For custom pin validators, put validate_pin() or validate_usage()
|
||||
# in gpio.py file in this directory.
|
||||
# For changing schema/pin schema, put COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA
|
||||
# in schema.py file in this directory.
|
||||
|
||||
from esphome import pins
|
||||
from esphome.components import libretiny
|
||||
from esphome.components.libretiny.const import (
|
||||
COMPONENT_BK72XX,
|
||||
KEY_COMPONENT_DATA,
|
||||
KEY_LIBRETINY,
|
||||
LibreTinyComponent,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
|
||||
from .boards import BK72XX_BOARDS, BK72XX_BOARD_PINS
|
||||
|
||||
CODEOWNERS = ["@kuba2k2"]
|
||||
AUTO_LOAD = ["libretiny"]
|
||||
|
||||
COMPONENT_DATA = LibreTinyComponent(
|
||||
name=COMPONENT_BK72XX,
|
||||
boards=BK72XX_BOARDS,
|
||||
board_pins=BK72XX_BOARD_PINS,
|
||||
pin_validation=None,
|
||||
usage_validation=None,
|
||||
)
|
||||
|
||||
|
||||
def _set_core_data(config):
|
||||
CORE.data[KEY_LIBRETINY] = {}
|
||||
CORE.data[KEY_LIBRETINY][KEY_COMPONENT_DATA] = COMPONENT_DATA
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = libretiny.BASE_SCHEMA
|
||||
|
||||
PIN_SCHEMA = libretiny.gpio.BASE_PIN_SCHEMA
|
||||
|
||||
CONFIG_SCHEMA.prepend_extra(_set_core_data)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
return await libretiny.component_to_code(config)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register("bk72xx", PIN_SCHEMA)
|
||||
async def pin_to_code(config):
|
||||
return await libretiny.gpio.component_pin_to_code(config)
|
1264
esphome/components/bk72xx/boards.py
Normal file
1264
esphome/components/bk72xx/boards.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -93,35 +93,27 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await uart.register_uart_device(var, config)
|
||||
|
||||
if CONF_VOLTAGE in config:
|
||||
conf = config[CONF_VOLTAGE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if voltage_config := config.get(CONF_VOLTAGE):
|
||||
sens = await sensor.new_sensor(voltage_config)
|
||||
cg.add(var.set_voltage_sensor(sens))
|
||||
if CONF_CURRENT_1 in config:
|
||||
conf = config[CONF_CURRENT_1]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if current_1_config := config.get(CONF_CURRENT_1):
|
||||
sens = await sensor.new_sensor(current_1_config)
|
||||
cg.add(var.set_current_sensor_1(sens))
|
||||
if CONF_CURRENT_2 in config:
|
||||
conf = config[CONF_CURRENT_2]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if current_2_config := config.get(CONF_CURRENT_2):
|
||||
sens = await sensor.new_sensor(current_2_config)
|
||||
cg.add(var.set_current_sensor_2(sens))
|
||||
if CONF_ACTIVE_POWER_1 in config:
|
||||
conf = config[CONF_ACTIVE_POWER_1]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if active_power_1_config := config.get(CONF_ACTIVE_POWER_1):
|
||||
sens = await sensor.new_sensor(active_power_1_config)
|
||||
cg.add(var.set_power_sensor_1(sens))
|
||||
if CONF_ACTIVE_POWER_2 in config:
|
||||
conf = config[CONF_ACTIVE_POWER_2]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if active_power_2_config := config.get(CONF_ACTIVE_POWER_2):
|
||||
sens = await sensor.new_sensor(active_power_2_config)
|
||||
cg.add(var.set_power_sensor_2(sens))
|
||||
if CONF_ENERGY_1 in config:
|
||||
conf = config[CONF_ENERGY_1]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if energy_1_config := config.get(CONF_ENERGY_1):
|
||||
sens = await sensor.new_sensor(energy_1_config)
|
||||
cg.add(var.set_energy_sensor_1(sens))
|
||||
if CONF_ENERGY_2 in config:
|
||||
conf = config[CONF_ENERGY_2]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if energy_2_config := config.get(CONF_ENERGY_2):
|
||||
sens = await sensor.new_sensor(energy_2_config)
|
||||
cg.add(var.set_energy_sensor_2(sens))
|
||||
if CONF_ENERGY_TOTAL in config:
|
||||
conf = config[CONF_ENERGY_TOTAL]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if energy_total_config := config.get(CONF_ENERGY_TOTAL):
|
||||
sens = await sensor.new_sensor(energy_total_config)
|
||||
cg.add(var.set_energy_sensor_sum(sens))
|
||||
|
@@ -79,27 +79,21 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await uart.register_uart_device(var, config)
|
||||
|
||||
if CONF_VOLTAGE in config:
|
||||
conf = config[CONF_VOLTAGE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if voltage_config := config.get(CONF_VOLTAGE):
|
||||
sens = await sensor.new_sensor(voltage_config)
|
||||
cg.add(var.set_voltage_sensor(sens))
|
||||
if CONF_CURRENT in config:
|
||||
conf = config[CONF_CURRENT]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if current_config := config.get(CONF_CURRENT):
|
||||
sens = await sensor.new_sensor(current_config)
|
||||
cg.add(var.set_current_sensor(sens))
|
||||
if CONF_POWER in config:
|
||||
conf = config[CONF_POWER]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if power_config := config.get(CONF_POWER):
|
||||
sens = await sensor.new_sensor(power_config)
|
||||
cg.add(var.set_power_sensor(sens))
|
||||
if CONF_ENERGY in config:
|
||||
conf = config[CONF_ENERGY]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if energy_config := config.get(CONF_ENERGY):
|
||||
sens = await sensor.new_sensor(energy_config)
|
||||
cg.add(var.set_energy_sensor(sens))
|
||||
if CONF_INTERNAL_TEMPERATURE in config:
|
||||
conf = config[CONF_INTERNAL_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if internal_temperature_config := config.get(CONF_INTERNAL_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(internal_temperature_config)
|
||||
cg.add(var.set_internal_temperature_sensor(sens))
|
||||
if CONF_EXTERNAL_TEMPERATURE in config:
|
||||
conf = config[CONF_EXTERNAL_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if external_temperature_config := config.get(CONF_EXTERNAL_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(external_temperature_config)
|
||||
cg.add(var.set_external_temperature_sensor(sens))
|
||||
|
@@ -71,23 +71,18 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await uart.register_uart_device(var, config)
|
||||
|
||||
if CONF_VOLTAGE in config:
|
||||
conf = config[CONF_VOLTAGE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if voltage_config := config.get(CONF_VOLTAGE):
|
||||
sens = await sensor.new_sensor(voltage_config)
|
||||
cg.add(var.set_voltage_sensor(sens))
|
||||
if CONF_CURRENT in config:
|
||||
conf = config[CONF_CURRENT]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if current_config := config.get(CONF_CURRENT):
|
||||
sens = await sensor.new_sensor(current_config)
|
||||
cg.add(var.set_current_sensor(sens))
|
||||
if CONF_POWER in config:
|
||||
conf = config[CONF_POWER]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if power_config := config.get(CONF_POWER):
|
||||
sens = await sensor.new_sensor(power_config)
|
||||
cg.add(var.set_power_sensor(sens))
|
||||
if CONF_ENERGY in config:
|
||||
conf = config[CONF_ENERGY]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if energy_config := config.get(CONF_ENERGY):
|
||||
sens = await sensor.new_sensor(energy_config)
|
||||
cg.add(var.set_energy_sensor(sens))
|
||||
if CONF_FREQUENCY in config:
|
||||
conf = config[CONF_FREQUENCY]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if frequency_config := config.get(CONF_FREQUENCY):
|
||||
sens = await sensor.new_sensor(frequency_config)
|
||||
cg.add(var.set_frequency_sensor(sens))
|
||||
|
@@ -129,32 +129,18 @@ async def characteristic_sensor_to_code(config):
|
||||
)
|
||||
cg.add(var.set_char_uuid128(uuid128))
|
||||
|
||||
if CONF_DESCRIPTOR_UUID in config:
|
||||
if len(config[CONF_DESCRIPTOR_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(
|
||||
var.set_descr_uuid16(
|
||||
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
|
||||
esp32_ble_tracker.bt_uuid32_format
|
||||
):
|
||||
cg.add(
|
||||
var.set_descr_uuid32(
|
||||
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
|
||||
esp32_ble_tracker.bt_uuid128_format
|
||||
):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(
|
||||
config[CONF_DESCRIPTOR_UUID]
|
||||
)
|
||||
if descriptor_uuid := config.get(CONF_DESCRIPTOR_UUID):
|
||||
if len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(var.set_descr_uuid16(esp32_ble_tracker.as_hex(descriptor_uuid)))
|
||||
elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(var.set_descr_uuid32(esp32_ble_tracker.as_hex(descriptor_uuid)))
|
||||
elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(descriptor_uuid)
|
||||
cg.add(var.set_descr_uuid128(uuid128))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
if lambda_config := config.get(CONF_LAMBDA):
|
||||
lambda_ = await cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(adv_data_t_const_ref, "x")], return_type=cg.float_
|
||||
lambda_config, [(adv_data_t_const_ref, "x")], return_type=cg.float_
|
||||
)
|
||||
cg.add(var.set_data_to_value(lambda_))
|
||||
|
||||
|
@@ -88,27 +88,13 @@ async def to_code(config):
|
||||
)
|
||||
cg.add(var.set_char_uuid128(uuid128))
|
||||
|
||||
if CONF_DESCRIPTOR_UUID in config:
|
||||
if len(config[CONF_DESCRIPTOR_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(
|
||||
var.set_descr_uuid16(
|
||||
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
|
||||
esp32_ble_tracker.bt_uuid32_format
|
||||
):
|
||||
cg.add(
|
||||
var.set_descr_uuid32(
|
||||
esp32_ble_tracker.as_hex(config[CONF_DESCRIPTOR_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_DESCRIPTOR_UUID]) == len(
|
||||
esp32_ble_tracker.bt_uuid128_format
|
||||
):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(
|
||||
config[CONF_DESCRIPTOR_UUID]
|
||||
)
|
||||
if descriptor_uuid := config:
|
||||
if len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(var.set_descr_uuid16(esp32_ble_tracker.as_hex(descriptor_uuid)))
|
||||
elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(var.set_descr_uuid32(esp32_ble_tracker.as_hex(descriptor_uuid)))
|
||||
elif len(descriptor_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(descriptor_uuid)
|
||||
cg.add(var.set_descr_uuid128(uuid128))
|
||||
|
||||
await cg.register_component(var, config)
|
||||
|
@@ -55,35 +55,27 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await esp32_ble_tracker.register_ble_device(var, config)
|
||||
|
||||
if CONF_MIN_RSSI in config:
|
||||
cg.add(var.set_minimum_rssi(config[CONF_MIN_RSSI]))
|
||||
if min_rssi := config.get(CONF_MIN_RSSI):
|
||||
cg.add(var.set_minimum_rssi(min_rssi))
|
||||
|
||||
if CONF_MAC_ADDRESS in config:
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
if mac_address := config.get(CONF_MAC_ADDRESS):
|
||||
cg.add(var.set_address(mac_address.as_hex))
|
||||
|
||||
if CONF_SERVICE_UUID in config:
|
||||
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(
|
||||
var.set_service_uuid16(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(
|
||||
var.set_service_uuid32(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(config[CONF_SERVICE_UUID])
|
||||
if service_uuid := config.get(CONF_SERVICE_UUID):
|
||||
if len(service_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(service_uuid)))
|
||||
elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(var.set_service_uuid32(esp32_ble_tracker.as_hex(service_uuid)))
|
||||
elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(service_uuid)
|
||||
cg.add(var.set_service_uuid128(uuid128))
|
||||
|
||||
if CONF_IBEACON_UUID in config:
|
||||
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(config[CONF_IBEACON_UUID]))
|
||||
if ibeacon_uuid := config.get(CONF_IBEACON_UUID):
|
||||
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(ibeacon_uuid))
|
||||
cg.add(var.set_ibeacon_uuid(ibeacon_uuid))
|
||||
|
||||
if CONF_IBEACON_MAJOR in config:
|
||||
cg.add(var.set_ibeacon_major(config[CONF_IBEACON_MAJOR]))
|
||||
if (ibeacon_major := config.get(CONF_IBEACON_MAJOR)) is not None:
|
||||
cg.add(var.set_ibeacon_major(ibeacon_major))
|
||||
|
||||
if CONF_IBEACON_MINOR in config:
|
||||
cg.add(var.set_ibeacon_minor(config[CONF_IBEACON_MINOR]))
|
||||
if (ibeacon_minor := config.get(CONF_IBEACON_MINOR)) is not None:
|
||||
cg.add(var.set_ibeacon_minor(ibeacon_minor))
|
||||
|
@@ -57,32 +57,24 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await esp32_ble_tracker.register_ble_device(var, config)
|
||||
|
||||
if CONF_MAC_ADDRESS in config:
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
if mac_address := config.get(CONF_MAC_ADDRESS):
|
||||
cg.add(var.set_address(mac_address.as_hex))
|
||||
|
||||
if CONF_SERVICE_UUID in config:
|
||||
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(
|
||||
var.set_service_uuid16(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(
|
||||
var.set_service_uuid32(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(config[CONF_SERVICE_UUID])
|
||||
if service_uuid := config.get(CONF_SERVICE_UUID):
|
||||
if len(service_uuid) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(service_uuid)))
|
||||
elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(var.set_service_uuid32(esp32_ble_tracker.as_hex(service_uuid)))
|
||||
elif len(service_uuid) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_reversed_hex_array(service_uuid)
|
||||
cg.add(var.set_service_uuid128(uuid128))
|
||||
|
||||
if CONF_IBEACON_UUID in config:
|
||||
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(config[CONF_IBEACON_UUID]))
|
||||
if ibeacon_uuid := config.get(CONF_IBEACON_UUID):
|
||||
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(ibeacon_uuid))
|
||||
cg.add(var.set_ibeacon_uuid(ibeacon_uuid))
|
||||
|
||||
if CONF_IBEACON_MAJOR in config:
|
||||
cg.add(var.set_ibeacon_major(config[CONF_IBEACON_MAJOR]))
|
||||
if (ibeacon_major := config.get(CONF_IBEACON_MAJOR)) is not None:
|
||||
cg.add(var.set_ibeacon_major(ibeacon_major))
|
||||
|
||||
if CONF_IBEACON_MINOR in config:
|
||||
cg.add(var.set_ibeacon_minor(config[CONF_IBEACON_MINOR]))
|
||||
if (ibeacon_minor := config.get(CONF_IBEACON_MINOR)) is not None:
|
||||
cg.add(var.set_ibeacon_minor(ibeacon_minor))
|
||||
|
@@ -98,22 +98,19 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
conf = config[CONF_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
cg.add(var.set_temperature_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_temperature_oversampling(temperature_config[CONF_OVERSAMPLING]))
|
||||
|
||||
if CONF_PRESSURE in config:
|
||||
conf = config[CONF_PRESSURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
sens = await sensor.new_sensor(pressure_config)
|
||||
cg.add(var.set_pressure_sensor(sens))
|
||||
cg.add(var.set_pressure_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING]))
|
||||
|
||||
if CONF_HUMIDITY in config:
|
||||
conf = config[CONF_HUMIDITY]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if humidity_config := config.get(CONF_HUMIDITY):
|
||||
sens = await sensor.new_sensor(humidity_config)
|
||||
cg.add(var.set_humidity_sensor(sens))
|
||||
cg.add(var.set_humidity_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_humidity_oversampling(humidity_config[CONF_OVERSAMPLING]))
|
||||
|
||||
cg.add(var.set_iir_filter(config[CONF_IIR_FILTER]))
|
||||
|
@@ -130,27 +130,23 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
conf = config[CONF_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
cg.add(var.set_temperature_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_temperature_oversampling(temperature_config[CONF_OVERSAMPLING]))
|
||||
|
||||
if CONF_PRESSURE in config:
|
||||
conf = config[CONF_PRESSURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
sens = await sensor.new_sensor(pressure_config)
|
||||
cg.add(var.set_pressure_sensor(sens))
|
||||
cg.add(var.set_pressure_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING]))
|
||||
|
||||
if CONF_HUMIDITY in config:
|
||||
conf = config[CONF_HUMIDITY]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if humidity_config := config.get(CONF_HUMIDITY):
|
||||
sens = await sensor.new_sensor(humidity_config)
|
||||
cg.add(var.set_humidity_sensor(sens))
|
||||
cg.add(var.set_humidity_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_humidity_oversampling(humidity_config[CONF_OVERSAMPLING]))
|
||||
|
||||
if CONF_GAS_RESISTANCE in config:
|
||||
conf = config[CONF_GAS_RESISTANCE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if gas_resistance_config := config.get(CONF_GAS_RESISTANCE):
|
||||
sens = await sensor.new_sensor(gas_resistance_config)
|
||||
cg.add(var.set_gas_resistance_sensor(sens))
|
||||
|
||||
cg.add(var.set_iir_filter(IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]))
|
||||
|
@@ -108,12 +108,13 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
async def setup_conf(config, key, hub):
|
||||
if key in config:
|
||||
conf = config[key]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if sensor_config := config.get(key):
|
||||
sens = await sensor.new_sensor(sensor_config)
|
||||
cg.add(getattr(hub, f"set_{key}_sensor")(sens))
|
||||
if CONF_SAMPLE_RATE in conf:
|
||||
cg.add(getattr(hub, f"set_{key}_sample_rate")(conf[CONF_SAMPLE_RATE]))
|
||||
if CONF_SAMPLE_RATE in sensor_config:
|
||||
cg.add(
|
||||
getattr(hub, f"set_{key}_sample_rate")(sensor_config[CONF_SAMPLE_RATE])
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
|
@@ -21,9 +21,8 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
|
||||
|
||||
async def setup_conf(config, key, hub):
|
||||
if key in config:
|
||||
conf = config[key]
|
||||
sens = await text_sensor.new_text_sensor(conf)
|
||||
if sensor_config := config.get(key):
|
||||
sens = await text_sensor.new_text_sensor(sensor_config)
|
||||
cg.add(getattr(hub, f"set_{key}_text_sensor")(sens))
|
||||
|
||||
|
||||
|
1
esphome/components/bmi160/__init__.py
Normal file
1
esphome/components/bmi160/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
CODEOWNERS = ["@flaviut"]
|
270
esphome/components/bmi160/bmi160.cpp
Normal file
270
esphome/components/bmi160/bmi160.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include "bmi160.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace bmi160 {
|
||||
|
||||
static const char *const TAG = "bmi160";
|
||||
|
||||
const uint8_t BMI160_REGISTER_CHIPID = 0x00;
|
||||
|
||||
const uint8_t BMI160_REGISTER_CMD = 0x7E;
|
||||
enum class Cmd : uint8_t {
|
||||
START_FOC = 0x03,
|
||||
ACCL_SET_PMU_MODE = 0b00010000, // last 2 bits are mode
|
||||
GYRO_SET_PMU_MODE = 0b00010100, // last 2 bits are mode
|
||||
MAG_SET_PMU_MODE = 0b00011000, // last 2 bits are mode
|
||||
PROG_NVM = 0xA0,
|
||||
FIFO_FLUSH = 0xB0,
|
||||
INT_RESET = 0xB1,
|
||||
SOFT_RESET = 0xB6,
|
||||
STEP_CNT_CLR = 0xB2,
|
||||
};
|
||||
enum class GyroPmuMode : uint8_t {
|
||||
SUSPEND = 0b00,
|
||||
NORMAL = 0b01,
|
||||
LOW_POWER = 0b10,
|
||||
};
|
||||
enum class AcclPmuMode : uint8_t {
|
||||
SUSPEND = 0b00,
|
||||
NORMAL = 0b01,
|
||||
FAST_STARTUP = 0b11,
|
||||
};
|
||||
enum class MagPmuMode : uint8_t {
|
||||
SUSPEND = 0b00,
|
||||
NORMAL = 0b01,
|
||||
LOW_POWER = 0b10,
|
||||
};
|
||||
|
||||
const uint8_t BMI160_REGISTER_ACCEL_CONFIG = 0x40;
|
||||
enum class AcclFilterMode : uint8_t {
|
||||
POWER_SAVING = 0b00000000,
|
||||
PERF = 0b10000000,
|
||||
};
|
||||
enum class AcclBandwidth : uint8_t {
|
||||
OSR4_AVG1 = 0b00000000,
|
||||
OSR2_AVG2 = 0b00010000,
|
||||
NORMAL_AVG4 = 0b00100000,
|
||||
RES_AVG8 = 0b00110000,
|
||||
RES_AVG16 = 0b01000000,
|
||||
RES_AVG32 = 0b01010000,
|
||||
RES_AVG64 = 0b01100000,
|
||||
RES_AVG128 = 0b01110000,
|
||||
};
|
||||
enum class AccelOutputDataRate : uint8_t {
|
||||
HZ_25_32 = 0b0001, // 25/32 Hz
|
||||
HZ_25_16 = 0b0010, // 25/16 Hz
|
||||
HZ_25_8 = 0b0011, // 25/8 Hz
|
||||
HZ_25_4 = 0b0100, // 25/4 Hz
|
||||
HZ_25_2 = 0b0101, // 25/2 Hz
|
||||
HZ_25 = 0b0110, // 25 Hz
|
||||
HZ_50 = 0b0111, // 50 Hz
|
||||
HZ_100 = 0b1000, // 100 Hz
|
||||
HZ_200 = 0b1001, // 200 Hz
|
||||
HZ_400 = 0b1010, // 400 Hz
|
||||
HZ_800 = 0b1011, // 800 Hz
|
||||
HZ_1600 = 0b1100, // 1600 Hz
|
||||
};
|
||||
const uint8_t BMI160_REGISTER_ACCEL_RANGE = 0x41;
|
||||
enum class AccelRange : uint8_t {
|
||||
RANGE_2G = 0b0011,
|
||||
RANGE_4G = 0b0101,
|
||||
RANGE_8G = 0b1000,
|
||||
RANGE_16G = 0b1100,
|
||||
};
|
||||
|
||||
const uint8_t BMI160_REGISTER_GYRO_CONFIG = 0x42;
|
||||
enum class GyroBandwidth : uint8_t {
|
||||
OSR4 = 0x00,
|
||||
OSR2 = 0x10,
|
||||
NORMAL = 0x20,
|
||||
};
|
||||
enum class GyroOuputDataRate : uint8_t {
|
||||
HZ_25 = 0x06,
|
||||
HZ_50 = 0x07,
|
||||
HZ_100 = 0x08,
|
||||
HZ_200 = 0x09,
|
||||
HZ_400 = 0x0A,
|
||||
HZ_800 = 0x0B,
|
||||
HZ_1600 = 0x0C,
|
||||
HZ_3200 = 0x0D,
|
||||
};
|
||||
const uint8_t BMI160_REGISTER_GYRO_RANGE = 0x43;
|
||||
enum class GyroRange : uint8_t {
|
||||
RANGE_2000_DPS = 0x0, // ±2000 °/s
|
||||
RANGE_1000_DPS = 0x1,
|
||||
RANGE_500_DPS = 0x2,
|
||||
RANGE_250_DPS = 0x3,
|
||||
RANGE_125_DPS = 0x4,
|
||||
};
|
||||
|
||||
const uint8_t BMI160_REGISTER_DATA_GYRO_X_LSB = 0x0C;
|
||||
const uint8_t BMI160_REGISTER_DATA_GYRO_X_MSB = 0x0D;
|
||||
const uint8_t BMI160_REGISTER_DATA_GYRO_Y_LSB = 0x0E;
|
||||
const uint8_t BMI160_REGISTER_DATA_GYRO_Y_MSB = 0x0F;
|
||||
const uint8_t BMI160_REGISTER_DATA_GYRO_Z_LSB = 0x10;
|
||||
const uint8_t BMI160_REGISTER_DATA_GYRO_Z_MSB = 0x11;
|
||||
const uint8_t BMI160_REGISTER_DATA_ACCEL_X_LSB = 0x12;
|
||||
const uint8_t BMI160_REGISTER_DATA_ACCEL_X_MSB = 0x13;
|
||||
const uint8_t BMI160_REGISTER_DATA_ACCEL_Y_LSB = 0x14;
|
||||
const uint8_t BMI160_REGISTER_DATA_ACCEL_Y_MSB = 0x15;
|
||||
const uint8_t BMI160_REGISTER_DATA_ACCEL_Z_LSB = 0x16;
|
||||
const uint8_t BMI160_REGISTER_DATA_ACCEL_Z_MSB = 0x17;
|
||||
const uint8_t BMI160_REGISTER_DATA_TEMP_LSB = 0x20;
|
||||
const uint8_t BMI160_REGISTER_DATA_TEMP_MSB = 0x21;
|
||||
|
||||
const float GRAVITY_EARTH = 9.80665f;
|
||||
|
||||
void BMI160Component::internal_setup_(int stage) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
ESP_LOGCONFIG(TAG, "Setting up BMI160...");
|
||||
uint8_t chipid;
|
||||
if (!this->read_byte(BMI160_REGISTER_CHIPID, &chipid) || (chipid != 0b11010001)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, " Bringing accelerometer out of sleep...");
|
||||
if (!this->write_byte(BMI160_REGISTER_CMD, (uint8_t) Cmd::ACCL_SET_PMU_MODE | (uint8_t) AcclPmuMode::NORMAL)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, " Waiting for accelerometer to wake up...");
|
||||
// need to wait (max delay in datasheet) because we can't send commands while another is in progress
|
||||
// min 5ms, 10ms
|
||||
this->set_timeout(10, [this]() { this->internal_setup_(1); });
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ESP_LOGV(TAG, " Bringing gyroscope out of sleep...");
|
||||
if (!this->write_byte(BMI160_REGISTER_CMD, (uint8_t) Cmd::GYRO_SET_PMU_MODE | (uint8_t) GyroPmuMode::NORMAL)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, " Waiting for gyroscope to wake up...");
|
||||
// wait between 51 & 81ms, doing 100 to be safe
|
||||
this->set_timeout(10, [this]() { this->internal_setup_(2); });
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ESP_LOGV(TAG, " Setting up Gyro Config...");
|
||||
uint8_t gyro_config = (uint8_t) GyroBandwidth::OSR4 | (uint8_t) GyroOuputDataRate::HZ_25;
|
||||
ESP_LOGV(TAG, " Output gyro_config: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(gyro_config));
|
||||
if (!this->write_byte(BMI160_REGISTER_GYRO_CONFIG, gyro_config)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, " Setting up Gyro Range...");
|
||||
uint8_t gyro_range = (uint8_t) GyroRange::RANGE_2000_DPS;
|
||||
ESP_LOGV(TAG, " Output gyro_range: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(gyro_range));
|
||||
if (!this->write_byte(BMI160_REGISTER_GYRO_RANGE, gyro_range)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, " Setting up Accel Config...");
|
||||
uint8_t accel_config =
|
||||
(uint8_t) AcclFilterMode::PERF | (uint8_t) AcclBandwidth::RES_AVG16 | (uint8_t) AccelOutputDataRate::HZ_25;
|
||||
ESP_LOGV(TAG, " Output accel_config: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(accel_config));
|
||||
if (!this->write_byte(BMI160_REGISTER_ACCEL_CONFIG, accel_config)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, " Setting up Accel Range...");
|
||||
uint8_t accel_range = (uint8_t) AccelRange::RANGE_16G;
|
||||
ESP_LOGV(TAG, " Output accel_range: 0b" BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(accel_range));
|
||||
if (!this->write_byte(BMI160_REGISTER_ACCEL_RANGE, accel_range)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
this->setup_complete_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BMI160Component::setup() { this->internal_setup_(0); }
|
||||
void BMI160Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "BMI160:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "Communication with BMI160 failed!");
|
||||
}
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
LOG_SENSOR(" ", "Acceleration X", this->accel_x_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration Y", this->accel_y_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration Z", this->accel_z_sensor_);
|
||||
LOG_SENSOR(" ", "Gyro X", this->gyro_x_sensor_);
|
||||
LOG_SENSOR(" ", "Gyro Y", this->gyro_y_sensor_);
|
||||
LOG_SENSOR(" ", "Gyro Z", this->gyro_z_sensor_);
|
||||
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
||||
}
|
||||
|
||||
i2c::ErrorCode BMI160Component::read_le_int16_(uint8_t reg, int16_t *value, uint8_t len) {
|
||||
uint8_t raw_data[len * 2];
|
||||
// read using read_register because we have little-endian data, and read_bytes_16 will swap it
|
||||
i2c::ErrorCode err = this->read_register(reg, raw_data, len * 2, true);
|
||||
if (err != i2c::ERROR_OK) {
|
||||
return err;
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
value[i] = (int16_t) ((uint16_t) raw_data[i * 2] | ((uint16_t) raw_data[i * 2 + 1] << 8));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void BMI160Component::update() {
|
||||
if (!this->setup_complete_) {
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, " Updating BMI160...");
|
||||
int16_t data[6];
|
||||
if (this->read_le_int16_(BMI160_REGISTER_DATA_GYRO_X_LSB, data, 6) != i2c::ERROR_OK) {
|
||||
this->status_set_warning();
|
||||
return;
|
||||
}
|
||||
|
||||
float gyro_x = (float) data[0] / (float) INT16_MAX * 2000.f;
|
||||
float gyro_y = (float) data[1] / (float) INT16_MAX * 2000.f;
|
||||
float gyro_z = (float) data[2] / (float) INT16_MAX * 2000.f;
|
||||
float accel_x = (float) data[3] / (float) INT16_MAX * 16 * GRAVITY_EARTH;
|
||||
float accel_y = (float) data[4] / (float) INT16_MAX * 16 * GRAVITY_EARTH;
|
||||
float accel_z = (float) data[5] / (float) INT16_MAX * 16 * GRAVITY_EARTH;
|
||||
|
||||
int16_t raw_temperature;
|
||||
if (this->read_le_int16_(BMI160_REGISTER_DATA_TEMP_LSB, &raw_temperature, 1) != i2c::ERROR_OK) {
|
||||
this->status_set_warning();
|
||||
return;
|
||||
}
|
||||
float temperature = (float) raw_temperature / (float) INT16_MAX * 64.5f + 23.f;
|
||||
|
||||
ESP_LOGD(TAG,
|
||||
"Got accel={x=%.3f m/s², y=%.3f m/s², z=%.3f m/s²}, "
|
||||
"gyro={x=%.3f °/s, y=%.3f °/s, z=%.3f °/s}, temp=%.3f°C",
|
||||
accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z, temperature);
|
||||
|
||||
if (this->accel_x_sensor_ != nullptr)
|
||||
this->accel_x_sensor_->publish_state(accel_x);
|
||||
if (this->accel_y_sensor_ != nullptr)
|
||||
this->accel_y_sensor_->publish_state(accel_y);
|
||||
if (this->accel_z_sensor_ != nullptr)
|
||||
this->accel_z_sensor_->publish_state(accel_z);
|
||||
|
||||
if (this->temperature_sensor_ != nullptr)
|
||||
this->temperature_sensor_->publish_state(temperature);
|
||||
|
||||
if (this->gyro_x_sensor_ != nullptr)
|
||||
this->gyro_x_sensor_->publish_state(gyro_x);
|
||||
if (this->gyro_y_sensor_ != nullptr)
|
||||
this->gyro_y_sensor_->publish_state(gyro_y);
|
||||
if (this->gyro_z_sensor_ != nullptr)
|
||||
this->gyro_z_sensor_->publish_state(gyro_z);
|
||||
|
||||
this->status_clear_warning();
|
||||
}
|
||||
float BMI160Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
} // namespace bmi160
|
||||
} // namespace esphome
|
44
esphome/components/bmi160/bmi160.h
Normal file
44
esphome/components/bmi160/bmi160.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace bmi160 {
|
||||
|
||||
class BMI160Component : public PollingComponent, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
|
||||
void update() override;
|
||||
|
||||
float get_setup_priority() const override;
|
||||
|
||||
void set_accel_x_sensor(sensor::Sensor *accel_x_sensor) { accel_x_sensor_ = accel_x_sensor; }
|
||||
void set_accel_y_sensor(sensor::Sensor *accel_y_sensor) { accel_y_sensor_ = accel_y_sensor; }
|
||||
void set_accel_z_sensor(sensor::Sensor *accel_z_sensor) { accel_z_sensor_ = accel_z_sensor; }
|
||||
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; }
|
||||
void set_gyro_x_sensor(sensor::Sensor *gyro_x_sensor) { gyro_x_sensor_ = gyro_x_sensor; }
|
||||
void set_gyro_y_sensor(sensor::Sensor *gyro_y_sensor) { gyro_y_sensor_ = gyro_y_sensor; }
|
||||
void set_gyro_z_sensor(sensor::Sensor *gyro_z_sensor) { gyro_z_sensor_ = gyro_z_sensor; }
|
||||
|
||||
protected:
|
||||
sensor::Sensor *accel_x_sensor_{nullptr};
|
||||
sensor::Sensor *accel_y_sensor_{nullptr};
|
||||
sensor::Sensor *accel_z_sensor_{nullptr};
|
||||
sensor::Sensor *temperature_sensor_{nullptr};
|
||||
sensor::Sensor *gyro_x_sensor_{nullptr};
|
||||
sensor::Sensor *gyro_y_sensor_{nullptr};
|
||||
sensor::Sensor *gyro_z_sensor_{nullptr};
|
||||
|
||||
void internal_setup_(int stage);
|
||||
bool setup_complete_{false};
|
||||
|
||||
/** reads `len` 16-bit little-endian integers from the given i2c register */
|
||||
i2c::ErrorCode read_le_int16_(uint8_t reg, int16_t *value, uint8_t len);
|
||||
};
|
||||
|
||||
} // namespace bmi160
|
||||
} // namespace esphome
|
102
esphome/components/bmi160/sensor.py
Normal file
102
esphome/components/bmi160/sensor.py
Normal file
@@ -0,0 +1,102 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_ACCELERATION_X,
|
||||
CONF_ACCELERATION_Y,
|
||||
CONF_ACCELERATION_Z,
|
||||
CONF_GYROSCOPE_X,
|
||||
CONF_GYROSCOPE_Y,
|
||||
CONF_GYROSCOPE_Z,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_METER_PER_SECOND_SQUARED,
|
||||
ICON_ACCELERATION_X,
|
||||
ICON_ACCELERATION_Y,
|
||||
ICON_ACCELERATION_Z,
|
||||
ICON_GYROSCOPE_X,
|
||||
ICON_GYROSCOPE_Y,
|
||||
ICON_GYROSCOPE_Z,
|
||||
UNIT_DEGREE_PER_SECOND,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bmi160_ns = cg.esphome_ns.namespace("bmi160")
|
||||
BMI160Component = bmi160_ns.class_(
|
||||
"BMI160Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
accel_schema = {
|
||||
"unit_of_measurement": UNIT_METER_PER_SECOND_SQUARED,
|
||||
"accuracy_decimals": 2,
|
||||
"state_class": STATE_CLASS_MEASUREMENT,
|
||||
}
|
||||
gyro_schema = {
|
||||
"unit_of_measurement": UNIT_DEGREE_PER_SECOND,
|
||||
"accuracy_decimals": 2,
|
||||
"state_class": STATE_CLASS_MEASUREMENT,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BMI160Component),
|
||||
cv.Optional(CONF_ACCELERATION_X): sensor.sensor_schema(
|
||||
icon=ICON_ACCELERATION_X,
|
||||
**accel_schema,
|
||||
),
|
||||
cv.Optional(CONF_ACCELERATION_Y): sensor.sensor_schema(
|
||||
icon=ICON_ACCELERATION_Y,
|
||||
**accel_schema,
|
||||
),
|
||||
cv.Optional(CONF_ACCELERATION_Z): sensor.sensor_schema(
|
||||
icon=ICON_ACCELERATION_Z,
|
||||
**accel_schema,
|
||||
),
|
||||
cv.Optional(CONF_GYROSCOPE_X): sensor.sensor_schema(
|
||||
icon=ICON_GYROSCOPE_X,
|
||||
**gyro_schema,
|
||||
),
|
||||
cv.Optional(CONF_GYROSCOPE_Y): sensor.sensor_schema(
|
||||
icon=ICON_GYROSCOPE_Y,
|
||||
**gyro_schema,
|
||||
),
|
||||
cv.Optional(CONF_GYROSCOPE_Z): sensor.sensor_schema(
|
||||
icon=ICON_GYROSCOPE_Z,
|
||||
**gyro_schema,
|
||||
),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x68))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
for d in ["x", "y", "z"]:
|
||||
accel_key = f"acceleration_{d}"
|
||||
if accel_key in config:
|
||||
sens = await sensor.new_sensor(config[accel_key])
|
||||
cg.add(getattr(var, f"set_accel_{d}_sensor")(sens))
|
||||
accel_key = f"gyroscope_{d}"
|
||||
if accel_key in config:
|
||||
sens = await sensor.new_sensor(config[accel_key])
|
||||
cg.add(getattr(var, f"set_gyro_{d}_sensor")(sens))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
cg.add(var.set_temperature_sensor(sens))
|
@@ -47,12 +47,10 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
conf = config[CONF_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature(sens))
|
||||
|
||||
if CONF_PRESSURE in config:
|
||||
conf = config[CONF_PRESSURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
sens = await sensor.new_sensor(pressure_config)
|
||||
cg.add(var.set_pressure(sens))
|
||||
|
@@ -83,16 +83,14 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
conf = config[CONF_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
cg.add(var.set_temperature_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_temperature_oversampling(temperature_config[CONF_OVERSAMPLING]))
|
||||
|
||||
if CONF_PRESSURE in config:
|
||||
conf = config[CONF_PRESSURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
sens = await sensor.new_sensor(pressure_config)
|
||||
cg.add(var.set_pressure_sensor(sens))
|
||||
cg.add(var.set_pressure_oversampling(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING]))
|
||||
|
||||
cg.add(var.set_iir_filter(config[CONF_IIR_FILTER]))
|
||||
|
@@ -87,14 +87,16 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
cg.add(var.set_iir_filter_config(config[CONF_IIR_FILTER]))
|
||||
if CONF_TEMPERATURE in config:
|
||||
conf = config[CONF_TEMPERATURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
cg.add(var.set_temperature_oversampling_config(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(
|
||||
var.set_temperature_oversampling_config(
|
||||
temperature_config[CONF_OVERSAMPLING]
|
||||
)
|
||||
)
|
||||
|
||||
if CONF_PRESSURE in config:
|
||||
conf = config[CONF_PRESSURE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
sens = await sensor.new_sensor(pressure_config)
|
||||
cg.add(var.set_pressure_sensor(sens))
|
||||
cg.add(var.set_pressure_oversampling_config(conf[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_pressure_oversampling_config(pressure_config[CONF_OVERSAMPLING]))
|
||||
|
0
esphome/components/bmp581/__init__.py
Normal file
0
esphome/components/bmp581/__init__.py
Normal file
596
esphome/components/bmp581/bmp581.cpp
Normal file
596
esphome/components/bmp581/bmp581.cpp
Normal file
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Adds support for Bosch's BMP581 high accuracy pressure and temperature sensor
|
||||
* - Component structure based on ESPHome's BMP3XX component (as of March, 2023)
|
||||
* - Implementation is easier as the sensor itself automatically compensates pressure for the temperature
|
||||
* - Temperature and pressure data is converted via simple divison operations in this component
|
||||
* - IIR filter level can independently be applied to temperature and pressure measurements
|
||||
* - Bosch's BMP5-Sensor-API was consulted to verify that sensor configuration is done correctly
|
||||
* - Copyright (c) 2022 Bosch Sensortec Gmbh, SPDX-License-Identifier: BSD-3-Clause
|
||||
* - This component uses forced power mode only so measurements are synchronized by the host
|
||||
* - All datasheet page references refer to Bosch Document Number BST-BMP581-DS004-04 (revision number 1.4)
|
||||
*/
|
||||
|
||||
#include "bmp581.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace bmp581 {
|
||||
|
||||
static const char *const TAG = "bmp581";
|
||||
|
||||
static const LogString *oversampling_to_str(Oversampling oversampling) {
|
||||
switch (oversampling) {
|
||||
case Oversampling::OVERSAMPLING_NONE:
|
||||
return LOG_STR("None");
|
||||
case Oversampling::OVERSAMPLING_X2:
|
||||
return LOG_STR("2x");
|
||||
case Oversampling::OVERSAMPLING_X4:
|
||||
return LOG_STR("4x");
|
||||
case Oversampling::OVERSAMPLING_X8:
|
||||
return LOG_STR("8x");
|
||||
case Oversampling::OVERSAMPLING_X16:
|
||||
return LOG_STR("16x");
|
||||
case Oversampling::OVERSAMPLING_X32:
|
||||
return LOG_STR("32x");
|
||||
case Oversampling::OVERSAMPLING_X64:
|
||||
return LOG_STR("64x");
|
||||
case Oversampling::OVERSAMPLING_X128:
|
||||
return LOG_STR("128x");
|
||||
default:
|
||||
return LOG_STR("");
|
||||
}
|
||||
}
|
||||
|
||||
static const LogString *iir_filter_to_str(IIRFilter filter) {
|
||||
switch (filter) {
|
||||
case IIRFilter::IIR_FILTER_OFF:
|
||||
return LOG_STR("OFF");
|
||||
case IIRFilter::IIR_FILTER_2:
|
||||
return LOG_STR("2x");
|
||||
case IIRFilter::IIR_FILTER_4:
|
||||
return LOG_STR("4x");
|
||||
case IIRFilter::IIR_FILTER_8:
|
||||
return LOG_STR("8x");
|
||||
case IIRFilter::IIR_FILTER_16:
|
||||
return LOG_STR("16x");
|
||||
case IIRFilter::IIR_FILTER_32:
|
||||
return LOG_STR("32x");
|
||||
case IIRFilter::IIR_FILTER_64:
|
||||
return LOG_STR("64x");
|
||||
case IIRFilter::IIR_FILTER_128:
|
||||
return LOG_STR("128x");
|
||||
default:
|
||||
return LOG_STR("");
|
||||
}
|
||||
}
|
||||
|
||||
void BMP581Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "BMP581:");
|
||||
|
||||
switch (this->error_code_) {
|
||||
case NONE:
|
||||
break;
|
||||
case ERROR_COMMUNICATION_FAILED:
|
||||
ESP_LOGE(TAG, " Communication with BMP581 failed!");
|
||||
break;
|
||||
case ERROR_WRONG_CHIP_ID:
|
||||
ESP_LOGE(TAG, " BMP581 has wrong chip ID - please verify you are using a BMP 581");
|
||||
break;
|
||||
case ERROR_SENSOR_RESET:
|
||||
ESP_LOGE(TAG, " BMP581 failed to reset");
|
||||
break;
|
||||
case ERROR_SENSOR_STATUS:
|
||||
ESP_LOGE(TAG, " BMP581 sensor status failed, there were NVM problems");
|
||||
break;
|
||||
case ERROR_PRIME_IIR_FAILED:
|
||||
ESP_LOGE(TAG, " BMP581's IIR Filter failed to prime with an initial measurement");
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, " BMP581 error code %d", (int) this->error_code_);
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_I2C_DEVICE(this);
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
|
||||
ESP_LOGCONFIG(TAG, " Measurement conversion time: %ums", this->conversion_time_);
|
||||
|
||||
if (this->temperature_sensor_) {
|
||||
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
||||
ESP_LOGCONFIG(TAG, " IIR Filter: %s", LOG_STR_ARG(iir_filter_to_str(this->iir_temperature_level_)));
|
||||
ESP_LOGCONFIG(TAG, " Oversampling: %s", LOG_STR_ARG(oversampling_to_str(this->temperature_oversampling_)));
|
||||
}
|
||||
|
||||
if (this->pressure_sensor_) {
|
||||
LOG_SENSOR(" ", "Pressure", this->pressure_sensor_);
|
||||
ESP_LOGCONFIG(TAG, " IIR Filter: %s", LOG_STR_ARG(iir_filter_to_str(this->iir_pressure_level_)));
|
||||
ESP_LOGCONFIG(TAG, " Oversampling: %s", LOG_STR_ARG(oversampling_to_str(this->pressure_oversampling_)));
|
||||
}
|
||||
}
|
||||
|
||||
void BMP581Component::setup() {
|
||||
/*
|
||||
* Setup goes through several stages, which follows the post-power-up procedure (page 18 of datasheet) and then sets
|
||||
* configured options
|
||||
* 1) Soft reboot
|
||||
* 2) Verify ASIC chip ID matches BMP581
|
||||
* 3) Verify sensor status (check if NVM is okay)
|
||||
* 4) Enable data ready interrupt
|
||||
* 5) Write oversampling settings and set internal configuration values
|
||||
* 6) Configure and prime IIR Filter(s), if enabled
|
||||
*/
|
||||
|
||||
this->error_code_ = NONE;
|
||||
ESP_LOGCONFIG(TAG, "Setting up BMP581...");
|
||||
|
||||
////////////////////
|
||||
// 1) Soft reboot //
|
||||
////////////////////
|
||||
|
||||
// Power-On-Reboot bit is asserted if sensor successfully reset
|
||||
if (!this->reset_()) {
|
||||
ESP_LOGE(TAG, "BMP581 failed to reset");
|
||||
|
||||
this->error_code_ = ERROR_SENSOR_RESET;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 2) Verify ASIC chip ID matches BMP581 //
|
||||
///////////////////////////////////////////
|
||||
|
||||
uint8_t chip_id;
|
||||
|
||||
// read chip id from sensor
|
||||
if (!this->read_byte(BMP581_CHIP_ID, &chip_id)) {
|
||||
ESP_LOGE(TAG, "Failed to read chip id");
|
||||
|
||||
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// verify id
|
||||
if (chip_id != BMP581_ASIC_ID) {
|
||||
ESP_LOGE(TAG, "Unknown chip ID, is this a BMP581?");
|
||||
|
||||
this->error_code_ = ERROR_WRONG_CHIP_ID;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// 3) Verify sensor status (check if NVM is okay) //
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
if (!this->read_byte(BMP581_STATUS, &this->status_.reg)) {
|
||||
ESP_LOGE(TAG, "Failed to read status register");
|
||||
|
||||
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// verify status_nvm_rdy bit (it is asserted if boot was successful)
|
||||
if (!(this->status_.bit.status_nvm_rdy)) {
|
||||
ESP_LOGE(TAG, "NVM not ready after boot");
|
||||
|
||||
this->error_code_ = ERROR_SENSOR_STATUS;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// verify status_nvm_err bit (it is asserted if an error is detected)
|
||||
if (this->status_.bit.status_nvm_err) {
|
||||
ESP_LOGE(TAG, "NVM error detected on boot");
|
||||
|
||||
this->error_code_ = ERROR_SENSOR_STATUS;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// 4) Enable data ready interrupt //
|
||||
////////////////////////////////////
|
||||
|
||||
// enable the data ready interrupt source
|
||||
if (!this->write_interrupt_source_settings_(true)) {
|
||||
ESP_LOGE(TAG, "Failed to write interrupt source register");
|
||||
|
||||
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 5) Write oversampling settings and set internal configuration values //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// configure pressure readings, if sensor is defined
|
||||
// otherwise, disable pressure oversampling
|
||||
if (this->pressure_sensor_) {
|
||||
this->osr_config_.bit.press_en = true;
|
||||
} else {
|
||||
this->pressure_oversampling_ = OVERSAMPLING_NONE;
|
||||
}
|
||||
|
||||
// write oversampling settings
|
||||
if (!this->write_oversampling_settings_(this->temperature_oversampling_, this->pressure_oversampling_)) {
|
||||
ESP_LOGE(TAG, "Failed to write oversampling register");
|
||||
|
||||
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// set output data rate to 4 Hz=0x19 (page 65 of datasheet)
|
||||
// - ?shouldn't? matter as this component only uses FORCED_MODE - datasheet is ambiguous
|
||||
// - If in NORMAL_MODE or NONSTOP_MODE, then this would still allow deep standby to save power
|
||||
// - will be written to BMP581 at next requested measurement
|
||||
this->odr_config_.bit.odr = 0x19;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
/// 6) Configure and prime IIR Filter(s), if enabled //
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
if ((this->iir_temperature_level_ != IIR_FILTER_OFF) || (this->iir_pressure_level_ != IIR_FILTER_OFF)) {
|
||||
if (!this->write_iir_settings_(this->iir_temperature_level_, this->iir_pressure_level_)) {
|
||||
ESP_LOGE(TAG, "Failed to write IIR configuration registers");
|
||||
|
||||
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->prime_iir_filter_()) {
|
||||
ESP_LOGE(TAG, "Failed to prime the IIR filter with an intiial measurement");
|
||||
|
||||
this->error_code_ = ERROR_PRIME_IIR_FAILED;
|
||||
this->mark_failed();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BMP581Component::update() {
|
||||
/*
|
||||
* Each update goes through several stages
|
||||
* 0) Verify either a temperature or pressure sensor is defined before proceeding
|
||||
* 1) Request a measurement
|
||||
* 2) Wait for measurement to finish (based on oversampling rates)
|
||||
* 3) Read data registers for temperature and pressure, if applicable
|
||||
* 4) Publish measurements to sensor(s), if applicable
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// 0) Verify either a temperature or pressure sensor is defined before proceeding //
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if ((!this->temperature_sensor_) && (!this->pressure_sensor_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// 1) Request a measurement //
|
||||
//////////////////////////////
|
||||
|
||||
ESP_LOGVV(TAG, "Requesting a measurement from sensor");
|
||||
|
||||
if (!this->start_measurement_()) {
|
||||
ESP_LOGW(TAG, "Failed to request forced measurement of sensor");
|
||||
this->status_set_warning();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// 2) Wait for measurement to finish (based on oversampling rates) //
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
ESP_LOGVV(TAG, "Measurement is expected to take %d ms to complete", this->conversion_time_);
|
||||
|
||||
this->set_timeout("measurement", this->conversion_time_, [this]() {
|
||||
float temperature = 0.0;
|
||||
float pressure = 0.0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// 3) Read data registers for temperature and pressure, if applicable //
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (this->pressure_sensor_) {
|
||||
if (!this->read_temperature_and_pressure_(temperature, pressure)) {
|
||||
ESP_LOGW(TAG, "Failed to read temperature and pressure measurements, skipping update");
|
||||
this->status_set_warning();
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!this->read_temperature_(temperature)) {
|
||||
ESP_LOGW(TAG, "Failed to read temperature measurement, skipping update");
|
||||
this->status_set_warning();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// 4) Publish measurements to sensor(s), if applicable //
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
if (this->temperature_sensor_) {
|
||||
this->temperature_sensor_->publish_state(temperature);
|
||||
}
|
||||
|
||||
if (this->pressure_sensor_) {
|
||||
this->pressure_sensor_->publish_state(pressure);
|
||||
}
|
||||
|
||||
this->status_clear_warning();
|
||||
});
|
||||
}
|
||||
|
||||
bool BMP581Component::check_data_readiness_() {
|
||||
// - verifies component is not internally in standby mode
|
||||
// - reads interrupt status register
|
||||
// - checks if data ready bit is asserted
|
||||
// - If true, then internally sets component to standby mode if in forced mode
|
||||
// - returns data readiness state
|
||||
|
||||
if (this->odr_config_.bit.pwr_mode == STANDBY_MODE) {
|
||||
ESP_LOGD(TAG, "Data is not ready, sensor is in standby mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t status;
|
||||
|
||||
if (!this->read_byte(BMP581_INT_STATUS, &status)) {
|
||||
ESP_LOGE(TAG, "Failed to read interrupt status register");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->int_status_.reg = status;
|
||||
|
||||
if (this->int_status_.bit.drdy_data_reg) {
|
||||
// If in forced mode, then set internal record of the power mode to STANDBY_MODE
|
||||
// - sensor automatically returns to standby mode after completing a forced measurement
|
||||
if (this->odr_config_.bit.pwr_mode == FORCED_MODE) {
|
||||
this->odr_config_.bit.pwr_mode = STANDBY_MODE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BMP581Component::prime_iir_filter_() {
|
||||
// - temporarily disables oversampling for a fast initial measurement; avoids slowing down ESPHome's startup process
|
||||
// - enables IIR filter flushing with forced measurements
|
||||
// - forces a measurement; flushing the IIR filter and priming it with a current value
|
||||
// - disables IIR filter flushing with forced measurements
|
||||
// - reverts to internally configured oversampling rates
|
||||
// - returns success of all register writes/priming
|
||||
|
||||
// store current internal oversampling settings to revert to after priming
|
||||
Oversampling current_temperature_oversampling = (Oversampling) this->osr_config_.bit.osr_t;
|
||||
Oversampling current_pressure_oversampling = (Oversampling) this->osr_config_.bit.osr_p;
|
||||
|
||||
// temporarily disables oversampling for temperature and pressure for a fast priming measurement
|
||||
if (!this->write_oversampling_settings_(OVERSAMPLING_NONE, OVERSAMPLING_NONE)) {
|
||||
ESP_LOGE(TAG, "Failed to write oversampling register");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// flush the IIR filter with forced measurements (we will only flush once)
|
||||
this->dsp_config_.bit.iir_flush_forced_en = true;
|
||||
if (!this->write_byte(BMP581_DSP, this->dsp_config_.reg)) {
|
||||
ESP_LOGE(TAG, "Failed to write IIR source register");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// forces an intial measurement
|
||||
// - this measurements flushes the IIR filter reflecting written DSP settings
|
||||
// - flushing with this initial reading avoids having the internal previous data aquisition being 0, which
|
||||
// (I)nfinitely affects future values
|
||||
if (!this->start_measurement_()) {
|
||||
ESP_LOGE(TAG, "Failed to request a forced measurement");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// wait for priming measurement to complete
|
||||
// - with oversampling disabled, the conversion time for a single measurement for pressure and temperature is
|
||||
// ceilf(1.05*(1.0+1.0)) = 3ms
|
||||
// - see page 12 of datasheet for details
|
||||
delay(3);
|
||||
|
||||
if (!this->check_data_readiness_()) {
|
||||
ESP_LOGE(TAG, "IIR priming measurement was not ready");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// disable IIR filter flushings on future forced measurements
|
||||
this->dsp_config_.bit.iir_flush_forced_en = false;
|
||||
if (!this->write_byte(BMP581_DSP, this->dsp_config_.reg)) {
|
||||
ESP_LOGE(TAG, "Failed to write IIR source register");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// revert oversampling rates to original settings
|
||||
return this->write_oversampling_settings_(current_temperature_oversampling, current_pressure_oversampling);
|
||||
}
|
||||
|
||||
bool BMP581Component::read_temperature_(float &temperature) {
|
||||
// - verifies data is ready to be read
|
||||
// - reads in 3 bytes of temperature data
|
||||
// - returns whether successful, where the the variable parameter contains
|
||||
// - the measured temperature (in degrees Celsius)
|
||||
|
||||
if (!this->check_data_readiness_()) {
|
||||
ESP_LOGW(TAG, "Data from sensor isn't ready, skipping this update");
|
||||
this->status_set_warning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t data[3];
|
||||
if (!this->read_bytes(BMP581_MEASUREMENT_DATA, &data[0], 3)) {
|
||||
ESP_LOGW(TAG, "Failed to read sensor's measurement data");
|
||||
this->status_set_warning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// temperature MSB is in data[2], LSB is in data[1], XLSB in data[0]
|
||||
int32_t raw_temp = (int32_t) data[2] << 16 | (int32_t) data[1] << 8 | (int32_t) data[0];
|
||||
temperature = (float) (raw_temp / 65536.0); // convert measurement to degrees Celsius (page 22 of datasheet)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BMP581Component::read_temperature_and_pressure_(float &temperature, float &pressure) {
|
||||
// - verifies data is ready to be read
|
||||
// - reads in 6 bytes of temperature data (3 for temeperature, 3 for pressure)
|
||||
// - returns whether successful, where the variable parameters contain
|
||||
// - the measured temperature (in degrees Celsius)
|
||||
// - the measured pressure (in Pa)
|
||||
|
||||
if (!this->check_data_readiness_()) {
|
||||
ESP_LOGW(TAG, "Data from sensor isn't ready, skipping this update");
|
||||
this->status_set_warning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t data[6];
|
||||
if (!this->read_bytes(BMP581_MEASUREMENT_DATA, &data[0], 6)) {
|
||||
ESP_LOGW(TAG, "Failed to read sensor's measurement data");
|
||||
this->status_set_warning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// temperature MSB is in data[2], LSB is in data[1], XLSB in data[0]
|
||||
int32_t raw_temp = (int32_t) data[2] << 16 | (int32_t) data[1] << 8 | (int32_t) data[0];
|
||||
temperature = (float) (raw_temp / 65536.0); // convert measurement to degrees Celsius (page 22 of datasheet)
|
||||
|
||||
// pressure MSB is in data[5], LSB is in data[4], XLSB in data[3]
|
||||
int32_t raw_press = (int32_t) data[5] << 16 | (int32_t) data[4] << 8 | (int32_t) data[3];
|
||||
pressure = (float) (raw_press / 64.0); // Divide by 2^6=64 for Pa (page 22 of datasheet)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BMP581Component::reset_() {
|
||||
// - writes reset command to the command register
|
||||
// - waits for sensor to complete reset
|
||||
// - returns the Power-On-Reboot interrupt status, which is asserted if successful
|
||||
|
||||
// writes reset command to BMP's command register
|
||||
if (!this->write_byte(BMP581_COMMAND, RESET_COMMAND)) {
|
||||
ESP_LOGE(TAG, "Failed to write reset command");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// t_{soft_res} = 2ms (page 11 of datasheet); time it takes to enter standby mode
|
||||
// - round up to 3 ms
|
||||
delay(3);
|
||||
|
||||
// read interrupt status register
|
||||
if (!this->read_byte(BMP581_INT_STATUS, &this->int_status_.reg)) {
|
||||
ESP_LOGE(TAG, "Failed to read interrupt status register");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Power-On-Reboot bit is asserted if sensor successfully reset
|
||||
return this->int_status_.bit.por;
|
||||
}
|
||||
|
||||
bool BMP581Component::start_measurement_() {
|
||||
// - only pushes the sensor into FORCED_MODE for a reading if already in STANDBY_MODE
|
||||
// - returns whether a measurement is in progress or has been initiated
|
||||
|
||||
if (this->odr_config_.bit.pwr_mode == STANDBY_MODE) {
|
||||
return this->write_power_mode_(FORCED_MODE);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool BMP581Component::write_iir_settings_(IIRFilter temperature_iir, IIRFilter pressure_iir) {
|
||||
// - ensures data registers store filtered values
|
||||
// - sets IIR filter levels on sensor
|
||||
// - matches other default settings on sensor
|
||||
// - writes configuration to the two relevant registers
|
||||
// - returns success or failure of write to the registers
|
||||
|
||||
// If the temperature/pressure IIR filter is configured, then ensure data registers store the filtered measurement
|
||||
this->dsp_config_.bit.shdw_sel_iir_t = (temperature_iir != IIR_FILTER_OFF);
|
||||
this->dsp_config_.bit.shdw_sel_iir_p = (pressure_iir != IIR_FILTER_OFF);
|
||||
|
||||
// set temperature and pressure IIR filter level to configured values
|
||||
this->iir_config_.bit.set_iir_t = temperature_iir;
|
||||
this->iir_config_.bit.set_iir_p = pressure_iir;
|
||||
|
||||
// enable pressure and temperature compensation (page 61 of datasheet)
|
||||
// - ?only relevant if IIR filter is applied?; the datasheet is ambiguous
|
||||
// - matches BMP's default setting
|
||||
this->dsp_config_.bit.comp_pt_en = 0x3;
|
||||
|
||||
// BMP581_DSP register and BMP581_DSP_IIR registers are successive
|
||||
// - allows us to write the IIR configuration with one command to both registers
|
||||
uint8_t register_data[2] = {this->dsp_config_.reg, this->iir_config_.reg};
|
||||
return this->write_bytes(BMP581_DSP, register_data, sizeof(register_data));
|
||||
}
|
||||
|
||||
bool BMP581Component::write_interrupt_source_settings_(bool data_ready_enable) {
|
||||
// - updates component's internal setting
|
||||
// - returns success or failure of write to interrupt source register
|
||||
|
||||
this->int_source_.bit.drdy_data_reg_en = data_ready_enable;
|
||||
|
||||
// write interrupt source register
|
||||
return this->write_byte(BMP581_INT_SOURCE, this->int_source_.reg);
|
||||
}
|
||||
|
||||
bool BMP581Component::write_oversampling_settings_(Oversampling temperature_oversampling,
|
||||
Oversampling pressure_oversampling) {
|
||||
// - updates component's internal setting
|
||||
// - returns success or failure of write to Over-Sampling Rate register
|
||||
|
||||
this->osr_config_.bit.osr_t = temperature_oversampling;
|
||||
this->osr_config_.bit.osr_p = pressure_oversampling;
|
||||
|
||||
return this->write_byte(BMP581_OSR, this->osr_config_.reg);
|
||||
}
|
||||
|
||||
bool BMP581Component::write_power_mode_(OperationMode mode) {
|
||||
// - updates the component's internal power mode
|
||||
// - returns success or failure of write to Output Data Rate register
|
||||
|
||||
this->odr_config_.bit.pwr_mode = mode;
|
||||
|
||||
// write odr register
|
||||
return this->write_byte(BMP581_ODR, this->odr_config_.reg);
|
||||
}
|
||||
|
||||
} // namespace bmp581
|
||||
} // namespace esphome
|
222
esphome/components/bmp581/bmp581.h
Normal file
222
esphome/components/bmp581/bmp581.h
Normal file
@@ -0,0 +1,222 @@
|
||||
// All datasheet page references refer to Bosch Document Number BST-BMP581-DS004-04 (revision number 1.4)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace bmp581 {
|
||||
|
||||
static const uint8_t BMP581_ASIC_ID = 0x50; // BMP581's ASIC chip ID (page 51 of datasheet)
|
||||
static const uint8_t RESET_COMMAND = 0xB6; // Soft reset command
|
||||
|
||||
// BMP581 Register Addresses
|
||||
enum {
|
||||
BMP581_CHIP_ID = 0x01, // read chip ID
|
||||
BMP581_INT_SOURCE = 0x15, // write interrupt sources
|
||||
BMP581_MEASUREMENT_DATA =
|
||||
0x1D, // read measurement registers, 0x1D-0x1F are temperature XLSB to MSB and 0x20-0x22 are pressure XLSB to MSB
|
||||
BMP581_INT_STATUS = 0x27, // read interrupt statuses
|
||||
BMP581_STATUS = 0x28, // read sensor status
|
||||
BMP581_DSP = 0x30, // write sensor configuration
|
||||
BMP581_DSP_IIR = 0x31, // write IIR filter configuration
|
||||
BMP581_OSR = 0x36, // write oversampling configuration
|
||||
BMP581_ODR = 0x37, // write data rate and power mode configuration
|
||||
BMP581_COMMAND = 0x7E // write sensor command
|
||||
};
|
||||
|
||||
// BMP581 Power mode operations
|
||||
enum OperationMode {
|
||||
STANDBY_MODE = 0x0, // no active readings
|
||||
NORMAL_MODE = 0x1, // read continuously at ODR configured rate and standby between
|
||||
FORCED_MODE = 0x2, // read sensor once (only reading mode used by this component)
|
||||
NONSTOP_MODE = 0x3 // read continuously with no standby
|
||||
};
|
||||
|
||||
// Temperature and pressure sensors can be oversampled to reduce noise
|
||||
enum Oversampling {
|
||||
OVERSAMPLING_NONE = 0x0,
|
||||
OVERSAMPLING_X2 = 0x1,
|
||||
OVERSAMPLING_X4 = 0x2,
|
||||
OVERSAMPLING_X8 = 0x3,
|
||||
OVERSAMPLING_X16 = 0x4,
|
||||
OVERSAMPLING_X32 = 0x5,
|
||||
OVERSAMPLING_X64 = 0x6,
|
||||
OVERSAMPLING_X128 = 0x7
|
||||
};
|
||||
|
||||
// Infinite Impulse Response filter reduces noise caused by ambient disturbances
|
||||
enum IIRFilter {
|
||||
IIR_FILTER_OFF = 0x0,
|
||||
IIR_FILTER_2 = 0x1,
|
||||
IIR_FILTER_4 = 0x2,
|
||||
IIR_FILTER_8 = 0x3,
|
||||
IIR_FILTER_16 = 0x4,
|
||||
IIR_FILTER_32 = 0x5,
|
||||
IIR_FILTER_64 = 0x6,
|
||||
IIR_FILTER_128 = 0x7
|
||||
};
|
||||
|
||||
class BMP581Component : public PollingComponent, public i2c::I2CDevice {
|
||||
public:
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
|
||||
void dump_config() override;
|
||||
|
||||
void setup() override;
|
||||
void update() override;
|
||||
|
||||
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { this->temperature_sensor_ = temperature_sensor; }
|
||||
void set_pressure_sensor(sensor::Sensor *pressure_sensor) { this->pressure_sensor_ = pressure_sensor; }
|
||||
|
||||
void set_temperature_oversampling_config(Oversampling temperature_oversampling) {
|
||||
this->temperature_oversampling_ = temperature_oversampling;
|
||||
}
|
||||
void set_pressure_oversampling_config(Oversampling pressure_oversampling) {
|
||||
this->pressure_oversampling_ = pressure_oversampling;
|
||||
}
|
||||
|
||||
void set_temperature_iir_filter_config(IIRFilter iir_temperature_level) {
|
||||
this->iir_temperature_level_ = iir_temperature_level;
|
||||
}
|
||||
void set_pressure_iir_filter_config(IIRFilter iir_pressure_level) { this->iir_pressure_level_ = iir_pressure_level; }
|
||||
|
||||
void set_conversion_time(uint8_t conversion_time) { this->conversion_time_ = conversion_time; }
|
||||
|
||||
protected:
|
||||
sensor::Sensor *temperature_sensor_{nullptr};
|
||||
sensor::Sensor *pressure_sensor_{nullptr};
|
||||
|
||||
Oversampling temperature_oversampling_;
|
||||
Oversampling pressure_oversampling_;
|
||||
|
||||
IIRFilter iir_temperature_level_;
|
||||
IIRFilter iir_pressure_level_;
|
||||
|
||||
// Stores the sensors conversion time needed for a measurement based on oversampling settings and datasheet (page 12)
|
||||
// Computed in Python during codegen
|
||||
uint8_t conversion_time_;
|
||||
|
||||
// Checks if the BMP581 has measurement data ready by checking the sensor's interrupts
|
||||
bool check_data_readiness_();
|
||||
|
||||
// Flushes the IIR filter and primes an initial reading
|
||||
bool prime_iir_filter_();
|
||||
|
||||
// Reads temperature data from sensor and converts data to measurement in degrees Celsius
|
||||
bool read_temperature_(float &temperature);
|
||||
// Reads temperature and pressure data from sensor and converts data to measurements in degrees Celsius and Pa
|
||||
bool read_temperature_and_pressure_(float &temperature, float &pressure);
|
||||
|
||||
// Soft resets the BMP581
|
||||
bool reset_();
|
||||
|
||||
// Initiates a measurement on sensor by switching to FORCED_MODE
|
||||
bool start_measurement_();
|
||||
|
||||
// Writes the IIR filter configuration to the DSP and DSP_IIR registers
|
||||
bool write_iir_settings_(IIRFilter temperature_iir, IIRFilter pressure_iir);
|
||||
|
||||
// Writes whether to enable the data ready interrupt to the interrupt source register
|
||||
bool write_interrupt_source_settings_(bool data_ready_enable);
|
||||
|
||||
// Writes the oversampling settings to the OSR register
|
||||
bool write_oversampling_settings_(Oversampling temperature_oversampling, Oversampling pressure_oversampling);
|
||||
|
||||
// Sets the power mode on the BMP581 by writing to the ODR register
|
||||
bool write_power_mode_(OperationMode mode);
|
||||
|
||||
enum ErrorCode {
|
||||
NONE = 0,
|
||||
ERROR_COMMUNICATION_FAILED,
|
||||
ERROR_WRONG_CHIP_ID,
|
||||
ERROR_SENSOR_STATUS,
|
||||
ERROR_SENSOR_RESET,
|
||||
ERROR_PRIME_IIR_FAILED
|
||||
} error_code_{NONE};
|
||||
|
||||
// BMP581's interrupt source register (address 0x15) to configure which interrupts are enabled (page 54 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t drdy_data_reg_en : 1; // Data ready interrupt enable
|
||||
uint8_t fifo_full_en : 1; // FIFO full interrupt enable
|
||||
uint8_t fifo_ths_en : 1; // FIFO threshold/watermark interrupt enable
|
||||
uint8_t oor_p_en : 1; // Pressure data out-of-range interrupt enable
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} int_source_ = {.reg = 0};
|
||||
|
||||
// BMP581's interrupt status register (address 0x27) to determine ensor's current state (page 58 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t drdy_data_reg : 1; // Data ready
|
||||
uint8_t fifo_full : 1; // FIFO full
|
||||
uint8_t fifo_ths : 1; // FIFO fhreshold/watermark
|
||||
uint8_t oor_p : 1; // Pressure data out-of-range
|
||||
uint8_t por : 1; // Power-On-Reset complete
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} int_status_ = {.reg = 0};
|
||||
|
||||
// BMP581's status register (address 0x28) to determine if sensor has setup correctly (page 58 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t status_core_rdy : 1;
|
||||
uint8_t status_nvm_rdy : 1; // asserted if NVM is ready of operations
|
||||
uint8_t status_nvm_err : 1; // asserted if NVM error
|
||||
uint8_t status_nvm_cmd_err : 1; // asserted if boot command error
|
||||
uint8_t status_boot_err_corrected : 1; // asserted if a boot error has been corrected
|
||||
uint8_t : 2;
|
||||
uint8_t st_crack_pass : 1; // asserted if crack check has executed without detecting a crack
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} status_ = {.reg = 0};
|
||||
|
||||
// BMP581's dsp register (address 0x30) to configure data registers iir selection (page 61 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t comp_pt_en : 2; // enable temperature and pressure compensation
|
||||
uint8_t iir_flush_forced_en : 1; // IIR filter is flushed in forced mode
|
||||
uint8_t shdw_sel_iir_t : 1; // temperature data register value selected before or after iir
|
||||
uint8_t fifo_sel_iir_t : 1; // FIFO temperature data register value secected before or after iir
|
||||
uint8_t shdw_sel_iir_p : 1; // pressure data register value selected before or after iir
|
||||
uint8_t fifo_sel_iir_p : 1; // FIFO pressure data register value selected before or after iir
|
||||
uint8_t oor_sel_iir_p : 1; // pressure out-of-range value selected before or after iir
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} dsp_config_ = {.reg = 0};
|
||||
|
||||
// BMP581's iir register (address 0x31) to configure iir filtering(page 62 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t set_iir_t : 3; // Temperature IIR filter coefficient
|
||||
uint8_t set_iir_p : 3; // Pressure IIR filter coefficient
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} iir_config_ = {.reg = 0};
|
||||
|
||||
// BMP581's OSR register (address 0x36) to configure Over-Sampling Rates (page 64 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t osr_t : 3; // Temperature oversampling
|
||||
uint8_t osr_p : 3; // Pressure oversampling
|
||||
uint8_t press_en : 1; // Enables pressure measurement
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} osr_config_ = {.reg = 0};
|
||||
|
||||
// BMP581's odr register (address 0x37) to configure output data rate and power mode (page 64 of datasheet)
|
||||
union {
|
||||
struct {
|
||||
uint8_t pwr_mode : 2; // power mode of sensor
|
||||
uint8_t odr : 5; // output data rate
|
||||
uint8_t deep_dis : 1; // deep standby disabled if asserted
|
||||
} bit;
|
||||
uint8_t reg;
|
||||
} odr_config_ = {.reg = 0};
|
||||
};
|
||||
|
||||
} // namespace bmp581
|
||||
} // namespace esphome
|
163
esphome/components/bmp581/sensor.py
Normal file
163
esphome/components/bmp581/sensor.py
Normal file
@@ -0,0 +1,163 @@
|
||||
import math
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_IIR_FILTER,
|
||||
CONF_OVERSAMPLING,
|
||||
CONF_PRESSURE,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PASCAL,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@kahrendt"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bmp581_ns = cg.esphome_ns.namespace("bmp581")
|
||||
|
||||
Oversampling = bmp581_ns.enum("Oversampling")
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
"NONE": Oversampling.OVERSAMPLING_NONE,
|
||||
"2X": Oversampling.OVERSAMPLING_X2,
|
||||
"4X": Oversampling.OVERSAMPLING_X4,
|
||||
"8X": Oversampling.OVERSAMPLING_X8,
|
||||
"16X": Oversampling.OVERSAMPLING_X16,
|
||||
"32X": Oversampling.OVERSAMPLING_X32,
|
||||
"64X": Oversampling.OVERSAMPLING_X64,
|
||||
"128X": Oversampling.OVERSAMPLING_X128,
|
||||
}
|
||||
|
||||
IIRFilter = bmp581_ns.enum("IIRFilter")
|
||||
IIR_FILTER_OPTIONS = {
|
||||
"OFF": IIRFilter.IIR_FILTER_OFF,
|
||||
"2X": IIRFilter.IIR_FILTER_2,
|
||||
"4X": IIRFilter.IIR_FILTER_4,
|
||||
"8X": IIRFilter.IIR_FILTER_8,
|
||||
"16X": IIRFilter.IIR_FILTER_16,
|
||||
"32X": IIRFilter.IIR_FILTER_32,
|
||||
"64X": IIRFilter.IIR_FILTER_64,
|
||||
"128X": IIRFilter.IIR_FILTER_128,
|
||||
}
|
||||
|
||||
BMP581Component = bmp581_ns.class_(
|
||||
"BMP581Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
|
||||
def compute_measurement_conversion_time(config):
|
||||
# - adds up sensor conversion time based on temperature and pressure oversampling rates given in datasheet
|
||||
# - returns a rounded up time in ms
|
||||
|
||||
# Page 12 of datasheet
|
||||
PRESSURE_OVERSAMPLING_CONVERSION_TIMES = {
|
||||
"NONE": 1.0,
|
||||
"2X": 1.7,
|
||||
"4X": 2.9,
|
||||
"8X": 5.4,
|
||||
"16X": 10.4,
|
||||
"32X": 20.4,
|
||||
"64X": 40.4,
|
||||
"128X": 80.4,
|
||||
}
|
||||
|
||||
# Page 12 of datasheet
|
||||
TEMPERATURE_OVERSAMPLING_CONVERSION_TIMES = {
|
||||
"NONE": 1.0,
|
||||
"2X": 1.1,
|
||||
"4X": 1.5,
|
||||
"8X": 2.1,
|
||||
"16X": 3.3,
|
||||
"32X": 5.8,
|
||||
"64X": 10.8,
|
||||
"128X": 20.8,
|
||||
}
|
||||
|
||||
pressure_conversion_time = (
|
||||
0.0 # No conversion time necessary without a pressure sensor
|
||||
)
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
pressure_conversion_time = PRESSURE_OVERSAMPLING_CONVERSION_TIMES[
|
||||
pressure_config.get(CONF_OVERSAMPLING)
|
||||
]
|
||||
|
||||
temperature_conversion_time = (
|
||||
1.0 # BMP581 always samples the temperature even if only reading pressure
|
||||
)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
temperature_conversion_time = TEMPERATURE_OVERSAMPLING_CONVERSION_TIMES[
|
||||
temperature_config.get(CONF_OVERSAMPLING)
|
||||
]
|
||||
|
||||
# Datasheet indicates a 5% possible error in each conversion time listed
|
||||
return math.ceil(1.05 * (pressure_conversion_time + temperature_conversion_time))
|
||||
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BMP581Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="NONE"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
cv.Optional(CONF_IIR_FILTER, default="OFF"): cv.enum(
|
||||
IIR_FILTER_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_PASCAL,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
cv.Optional(CONF_IIR_FILTER, default="OFF"): cv.enum(
|
||||
IIR_FILTER_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x46))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
if temperature_config := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature_config)
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
cg.add(
|
||||
var.set_temperature_oversampling_config(
|
||||
temperature_config[CONF_OVERSAMPLING]
|
||||
)
|
||||
)
|
||||
cg.add(
|
||||
var.set_temperature_iir_filter_config(temperature_config[CONF_IIR_FILTER])
|
||||
)
|
||||
|
||||
if pressure_config := config.get(CONF_PRESSURE):
|
||||
sens = await sensor.new_sensor(pressure_config)
|
||||
cg.add(var.set_pressure_sensor(sens))
|
||||
cg.add(var.set_pressure_oversampling_config(pressure_config[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_pressure_iir_filter_config(pressure_config[CONF_IIR_FILTER]))
|
||||
|
||||
cg.add(var.set_conversion_time(compute_measurement_conversion_time(config)))
|
@@ -12,6 +12,8 @@ static const uint8_t BP1658CJ_ADDR_START_3CH = 0x10;
|
||||
static const uint8_t BP1658CJ_ADDR_START_2CH = 0x20;
|
||||
static const uint8_t BP1658CJ_ADDR_START_5CH = 0x30;
|
||||
|
||||
static const uint8_t BP1658CJ_DELAY = 2;
|
||||
|
||||
void BP1658CJ::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up BP1658CJ Output Component...");
|
||||
this->data_pin_->setup();
|
||||
@@ -35,10 +37,14 @@ void BP1658CJ::loop() {
|
||||
uint8_t data[12];
|
||||
if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
||||
this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
|
||||
// Off / Sleep
|
||||
data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_STANDBY;
|
||||
for (int i = 1; i < 12; i++)
|
||||
data[i] = 0;
|
||||
|
||||
// First turn all channels off
|
||||
data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_START_5CH;
|
||||
this->write_buffer_(data, 12);
|
||||
// Then sleep
|
||||
data[0] = BP1658CJ_MODEL_ID + BP1658CJ_ADDR_STANDBY;
|
||||
this->write_buffer_(data, 12);
|
||||
} else if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
||||
(this->pwm_amounts_[3] > 0 || this->pwm_amounts_[4] > 0)) {
|
||||
@@ -81,27 +87,41 @@ void BP1658CJ::set_channel_value_(uint8_t channel, uint16_t value) {
|
||||
}
|
||||
this->pwm_amounts_[channel] = value;
|
||||
}
|
||||
|
||||
void BP1658CJ::write_bit_(bool value) {
|
||||
this->clock_pin_->digital_write(false);
|
||||
this->data_pin_->digital_write(value);
|
||||
this->clock_pin_->digital_write(true);
|
||||
|
||||
delayMicroseconds(BP1658CJ_DELAY);
|
||||
|
||||
this->clock_pin_->digital_write(false);
|
||||
}
|
||||
|
||||
void BP1658CJ::write_byte_(uint8_t data) {
|
||||
for (uint8_t mask = 0x80; mask; mask >>= 1) {
|
||||
this->write_bit_(data & mask);
|
||||
delayMicroseconds(BP1658CJ_DELAY);
|
||||
}
|
||||
this->clock_pin_->digital_write(false);
|
||||
this->data_pin_->digital_write(true);
|
||||
|
||||
// ack bit
|
||||
this->data_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||
this->clock_pin_->digital_write(true);
|
||||
|
||||
delayMicroseconds(BP1658CJ_DELAY);
|
||||
|
||||
this->clock_pin_->digital_write(false);
|
||||
this->data_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
}
|
||||
|
||||
void BP1658CJ::write_buffer_(uint8_t *buffer, uint8_t size) {
|
||||
this->data_pin_->digital_write(false);
|
||||
this->clock_pin_->digital_write(false);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
this->write_byte_(buffer[i]);
|
||||
delayMicroseconds(BP1658CJ_DELAY);
|
||||
}
|
||||
this->clock_pin_->digital_write(false);
|
||||
|
||||
this->clock_pin_->digital_write(true);
|
||||
this->data_pin_->digital_write(true);
|
||||
}
|
||||
|
@@ -17,12 +17,16 @@ static const uint8_t BP5758D_ADDR_START_2CH = 0b00100000;
|
||||
static const uint8_t BP5758D_ADDR_START_5CH = 0b00110000;
|
||||
static const uint8_t BP5758D_ALL_DATA_CHANNEL_ENABLEMENT = 0b00011111;
|
||||
|
||||
static const uint8_t BP5758D_DELAY = 2;
|
||||
|
||||
void BP5758D::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up BP5758D Output Component...");
|
||||
this->data_pin_->setup();
|
||||
this->data_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->clock_pin_->setup();
|
||||
this->clock_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->channel_current_.resize(5, 0);
|
||||
this->pwm_amounts_.resize(5, 0);
|
||||
}
|
||||
@@ -39,10 +43,14 @@ void BP5758D::loop() {
|
||||
uint8_t data[17];
|
||||
if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
||||
this->pwm_amounts_[3] == 0 && this->pwm_amounts_[4] == 0) {
|
||||
// Off / Sleep
|
||||
data[0] = BP5758D_MODEL_ID + BP5758D_ADDR_STANDBY;
|
||||
for (int i = 1; i < 16; i++)
|
||||
for (int i = 1; i < 17; i++)
|
||||
data[i] = 0;
|
||||
|
||||
// First turn all channels off
|
||||
data[0] = BP5758D_MODEL_ID + BP5758D_ADDR_START_5CH;
|
||||
this->write_buffer_(data, 17);
|
||||
// Then sleep
|
||||
data[0] = BP5758D_MODEL_ID + BP5758D_ADDR_STANDBY;
|
||||
this->write_buffer_(data, 17);
|
||||
} else if (this->pwm_amounts_[0] == 0 && this->pwm_amounts_[1] == 0 && this->pwm_amounts_[2] == 0 &&
|
||||
(this->pwm_amounts_[3] > 0 || this->pwm_amounts_[4] > 0)) {
|
||||
@@ -119,28 +127,42 @@ void BP5758D::set_channel_value_(uint8_t channel, uint16_t value) {
|
||||
void BP5758D::set_channel_current_(uint8_t channel, uint8_t current) { this->channel_current_[channel] = current; }
|
||||
|
||||
void BP5758D::write_bit_(bool value) {
|
||||
this->clock_pin_->digital_write(false);
|
||||
this->data_pin_->digital_write(value);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->clock_pin_->digital_write(true);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->clock_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
}
|
||||
|
||||
void BP5758D::write_byte_(uint8_t data) {
|
||||
for (uint8_t mask = 0x80; mask; mask >>= 1) {
|
||||
this->write_bit_(data & mask);
|
||||
}
|
||||
this->clock_pin_->digital_write(false);
|
||||
this->data_pin_->digital_write(true);
|
||||
|
||||
// ack bit
|
||||
this->data_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||
this->clock_pin_->digital_write(true);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->clock_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->data_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
}
|
||||
|
||||
void BP5758D::write_buffer_(uint8_t *buffer, uint8_t size) {
|
||||
this->data_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->clock_pin_->digital_write(false);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
this->write_byte_(buffer[i]);
|
||||
}
|
||||
this->clock_pin_->digital_write(false);
|
||||
|
||||
this->clock_pin_->digital_write(true);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
this->data_pin_->digital_write(true);
|
||||
delayMicroseconds(BP5758D_DELAY);
|
||||
}
|
||||
|
||||
} // namespace bp5758d
|
||||
|
@@ -85,11 +85,11 @@ async def setup_button_core_(var, config):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||
if device_class := config.get(CONF_DEVICE_CLASS):
|
||||
cg.add(var.set_device_class(device_class))
|
||||
|
||||
if CONF_MQTT_ID in config:
|
||||
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
||||
if mqtt_id := config.get(CONF_MQTT_ID):
|
||||
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
||||
await mqtt.register_mqtt_component(mqtt_, config)
|
||||
|
||||
|
||||
|
@@ -18,10 +18,10 @@ CONF_ON_FRAME = "on_frame"
|
||||
|
||||
def validate_id(config):
|
||||
if CONF_CAN_ID in config:
|
||||
id_value = config[CONF_CAN_ID]
|
||||
can_id = config[CONF_CAN_ID]
|
||||
id_ext = config[CONF_USE_EXTENDED_ID]
|
||||
if not id_ext:
|
||||
if id_value > 0x7FF:
|
||||
if can_id > 0x7FF:
|
||||
raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
|
||||
return config
|
||||
|
||||
@@ -46,9 +46,13 @@ CanbusTrigger = canbus_ns.class_(
|
||||
CanSpeed = canbus_ns.enum("CAN_SPEED")
|
||||
|
||||
CAN_SPEEDS = {
|
||||
"1KBPS": CanSpeed.CAN_1KBPS,
|
||||
"5KBPS": CanSpeed.CAN_5KBPS,
|
||||
"10KBPS": CanSpeed.CAN_10KBPS,
|
||||
"12K5BPS": CanSpeed.CAN_12K5BPS,
|
||||
"16KBPS": CanSpeed.CAN_16KBPS,
|
||||
"20KBPS": CanSpeed.CAN_20KBPS,
|
||||
"25KBPS": CanSpeed.CAN_25KBPS,
|
||||
"31K25BPS": CanSpeed.CAN_31K25BPS,
|
||||
"33KBPS": CanSpeed.CAN_33KBPS,
|
||||
"40KBPS": CanSpeed.CAN_40KBPS,
|
||||
@@ -61,9 +65,9 @@ CAN_SPEEDS = {
|
||||
"200KBPS": CanSpeed.CAN_200KBPS,
|
||||
"250KBPS": CanSpeed.CAN_250KBPS,
|
||||
"500KBPS": CanSpeed.CAN_500KBPS,
|
||||
"800KBPS": CanSpeed.CAN_800KBPS,
|
||||
"1000KBPS": CanSpeed.CAN_1000KBPS,
|
||||
}
|
||||
|
||||
CANBUS_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
||||
@@ -145,25 +149,21 @@ async def canbus_action_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(var, config[CONF_CANBUS_ID])
|
||||
|
||||
if CONF_CAN_ID in config:
|
||||
can_id = await cg.templatable(config[CONF_CAN_ID], args, cg.uint32)
|
||||
if can_id := config.get(CONF_CAN_ID):
|
||||
can_id = await cg.templatable(can_id, args, cg.uint32)
|
||||
cg.add(var.set_can_id(can_id))
|
||||
use_extended_id = await cg.templatable(
|
||||
config[CONF_USE_EXTENDED_ID], args, cg.uint32
|
||||
)
|
||||
cg.add(var.set_use_extended_id(use_extended_id))
|
||||
cg.add(var.set_use_extended_id(config[CONF_USE_EXTENDED_ID]))
|
||||
|
||||
remote_transmission_request = await cg.templatable(
|
||||
config[CONF_REMOTE_TRANSMISSION_REQUEST], args, bool
|
||||
cg.add(
|
||||
var.set_remote_transmission_request(config[CONF_REMOTE_TRANSMISSION_REQUEST])
|
||||
)
|
||||
cg.add(var.set_remote_transmission_request(remote_transmission_request))
|
||||
|
||||
data = config[CONF_DATA]
|
||||
if isinstance(data, bytes):
|
||||
data = [int(x) for x in data]
|
||||
if cg.is_template(data):
|
||||
templ = await cg.templatable(data, args, cg.std_vector.template(cg.uint8))
|
||||
cg.add(var.set_data_template(templ))
|
||||
else:
|
||||
if isinstance(data, bytes):
|
||||
data = [int(x) for x in data]
|
||||
cg.add(var.set_data_static(data))
|
||||
return var
|
||||
|
@@ -19,9 +19,13 @@ enum Error : uint8_t {
|
||||
};
|
||||
|
||||
enum CanSpeed : uint8_t {
|
||||
CAN_1KBPS,
|
||||
CAN_5KBPS,
|
||||
CAN_10KBPS,
|
||||
CAN_12K5BPS,
|
||||
CAN_16KBPS,
|
||||
CAN_20KBPS,
|
||||
CAN_25KBPS,
|
||||
CAN_31K25BPS,
|
||||
CAN_33KBPS,
|
||||
CAN_40KBPS,
|
||||
@@ -34,6 +38,7 @@ enum CanSpeed : uint8_t {
|
||||
CAN_200KBPS,
|
||||
CAN_250KBPS,
|
||||
CAN_500KBPS,
|
||||
CAN_800KBPS,
|
||||
CAN_1000KBPS
|
||||
};
|
||||
|
||||
|
@@ -9,7 +9,7 @@ CONF_ALLOW_MULTIPLE_TOUCHES = "allow_multiple_touches"
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["binary_sensor", "output"]
|
||||
CODEOWNERS = ["@MrEditor97"]
|
||||
CODEOWNERS = ["@mreditor97"]
|
||||
|
||||
cap1188_ns = cg.esphome_ns.namespace("cap1188")
|
||||
CONF_CAP1188_ID = "cap1188_id"
|
||||
@@ -37,8 +37,8 @@ async def to_code(config):
|
||||
cg.add(var.set_touch_threshold(config[CONF_TOUCH_THRESHOLD]))
|
||||
cg.add(var.set_allow_multiple_touches(config[CONF_ALLOW_MULTIPLE_TOUCHES]))
|
||||
|
||||
if CONF_RESET_PIN in config:
|
||||
pin = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
||||
if reset_pin_config := config.get(CONF_RESET_PIN):
|
||||
pin = await cg.gpio_pin_expression(reset_pin_config)
|
||||
cg.add(var.set_reset_pin(pin))
|
||||
|
||||
await cg.register_component(var, config)
|
||||
|
@@ -2,7 +2,13 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import web_server_base
|
||||
from esphome.components.web_server_base import CONF_WEB_SERVER_BASE_ID
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_BK72XX,
|
||||
PLATFORM_RTL87XX,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority, CORE
|
||||
|
||||
AUTO_LOAD = ["web_server_base"]
|
||||
@@ -21,7 +27,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
cv.only_on(["esp32", "esp8266"]),
|
||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
|
||||
)
|
||||
|
||||
|
||||
@@ -39,3 +45,5 @@ async def to_code(config):
|
||||
cg.add_library("WiFi", None)
|
||||
if CORE.is_esp8266:
|
||||
cg.add_library("DNSServer", None)
|
||||
if CORE.is_libretiny:
|
||||
cg.add_library("DNSServer", None)
|
||||
|
@@ -48,7 +48,7 @@ void CaptivePortal::start() {
|
||||
this->dns_server_ = make_unique<DNSServer>();
|
||||
this->dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
|
||||
network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip();
|
||||
this->dns_server_->start(53, "*", (uint32_t) ip);
|
||||
this->dns_server_->start(53, "*", IPAddress(ip));
|
||||
#endif
|
||||
|
||||
this->base_->get_server()->onNotFound([this](AsyncWebServerRequest *req) {
|
||||
|
@@ -69,16 +69,16 @@ async def to_code(config):
|
||||
sens = await sensor.new_sensor(config[CONF_TVOC])
|
||||
cg.add(var.set_tvoc(sens))
|
||||
|
||||
if CONF_VERSION in config:
|
||||
sens = await text_sensor.new_text_sensor(config[CONF_VERSION])
|
||||
if version_config := config.get(CONF_VERSION):
|
||||
sens = await text_sensor.new_text_sensor(version_config)
|
||||
cg.add(var.set_version(sens))
|
||||
|
||||
if CONF_BASELINE in config:
|
||||
cg.add(var.set_baseline(config[CONF_BASELINE]))
|
||||
if (baseline := config.get(CONF_BASELINE)) is not None:
|
||||
cg.add(var.set_baseline(baseline))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await cg.get_variable(config[CONF_TEMPERATURE])
|
||||
if temperature_id := config.get(CONF_TEMPERATURE):
|
||||
sens = await cg.get_variable(temperature_id)
|
||||
cg.add(var.set_temperature(sens))
|
||||
if CONF_HUMIDITY in config:
|
||||
sens = await cg.get_variable(config[CONF_HUMIDITY])
|
||||
if humidity_id := config.get(CONF_HUMIDITY):
|
||||
sens = await cg.get_variable(humidity_id)
|
||||
cg.add(var.set_humidity(sens))
|
||||
|
@@ -127,8 +127,12 @@ def single_visual_temperature(value):
|
||||
|
||||
# Actions
|
||||
ControlAction = climate_ns.class_("ControlAction", automation.Action)
|
||||
StateTrigger = climate_ns.class_("StateTrigger", automation.Trigger.template())
|
||||
ControlTrigger = climate_ns.class_("ControlTrigger", automation.Trigger.template())
|
||||
StateTrigger = climate_ns.class_(
|
||||
"StateTrigger", automation.Trigger.template(Climate.operator("ref"))
|
||||
)
|
||||
ControlTrigger = climate_ns.class_(
|
||||
"ControlTrigger", automation.Trigger.template(ClimateCall.operator("ref"))
|
||||
)
|
||||
|
||||
VISUAL_TEMPERATURE_STEP_SCHEMA = cv.Any(
|
||||
single_visual_temperature,
|
||||
@@ -322,11 +326,15 @@ async def setup_climate_core_(var, config):
|
||||
|
||||
for conf in config.get(CONF_ON_STATE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
await automation.build_automation(
|
||||
trigger, [(Climate.operator("ref"), "x")], conf
|
||||
)
|
||||
|
||||
for conf in config.get(CONF_ON_CONTROL, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [], conf)
|
||||
await automation.build_automation(
|
||||
trigger, [(ClimateCall.operator("ref"), "x")], conf
|
||||
)
|
||||
|
||||
|
||||
async def register_climate(var, config):
|
||||
|
@@ -42,17 +42,17 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
|
||||
Climate *climate_;
|
||||
};
|
||||
|
||||
class ControlTrigger : public Trigger<> {
|
||||
class ControlTrigger : public Trigger<ClimateCall &> {
|
||||
public:
|
||||
ControlTrigger(Climate *climate) {
|
||||
climate->add_on_control_callback([this]() { this->trigger(); });
|
||||
climate->add_on_control_callback([this](ClimateCall &x) { this->trigger(x); });
|
||||
}
|
||||
};
|
||||
|
||||
class StateTrigger : public Trigger<> {
|
||||
class StateTrigger : public Trigger<Climate &> {
|
||||
public:
|
||||
StateTrigger(Climate *climate) {
|
||||
climate->add_on_state_callback([this]() { this->trigger(); });
|
||||
climate->add_on_state_callback([this](Climate &x) { this->trigger(x); });
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -7,6 +7,7 @@ namespace climate {
|
||||
static const char *const TAG = "climate";
|
||||
|
||||
void ClimateCall::perform() {
|
||||
this->parent_->control_callback_.call(*this);
|
||||
ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
|
||||
this->validate_();
|
||||
if (this->mode_.has_value()) {
|
||||
@@ -44,7 +45,6 @@ void ClimateCall::perform() {
|
||||
if (this->target_temperature_high_.has_value()) {
|
||||
ESP_LOGD(TAG, " Target Temperature High: %.2f", *this->target_temperature_high_);
|
||||
}
|
||||
this->parent_->control_callback_.call();
|
||||
this->parent_->control(*this);
|
||||
}
|
||||
void ClimateCall::validate_() {
|
||||
@@ -213,6 +213,8 @@ ClimateCall &ClimateCall::set_preset(const std::string &preset) {
|
||||
this->set_preset(CLIMATE_PRESET_SLEEP);
|
||||
} else if (str_equals_case_insensitive(preset, "ACTIVITY")) {
|
||||
this->set_preset(CLIMATE_PRESET_ACTIVITY);
|
||||
} else if (str_equals_case_insensitive(preset, "NONE")) {
|
||||
this->set_preset(CLIMATE_PRESET_NONE);
|
||||
} else {
|
||||
if (this->parent_->get_traits().supports_custom_preset(preset)) {
|
||||
this->custom_preset_ = preset;
|
||||
@@ -300,11 +302,11 @@ ClimateCall &ClimateCall::set_swing_mode(optional<ClimateSwingMode> swing_mode)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Climate::add_on_state_callback(std::function<void()> &&callback) {
|
||||
void Climate::add_on_state_callback(std::function<void(Climate &)> &&callback) {
|
||||
this->state_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void Climate::add_on_control_callback(std::function<void()> &&callback) {
|
||||
void Climate::add_on_control_callback(std::function<void(ClimateCall &)> &&callback) {
|
||||
this->control_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
@@ -408,7 +410,7 @@ void Climate::publish_state() {
|
||||
}
|
||||
|
||||
// Send state to frontend
|
||||
this->state_callback_.call();
|
||||
this->state_callback_.call(*this);
|
||||
// Save state
|
||||
this->save_state_();
|
||||
}
|
||||
|
@@ -198,7 +198,7 @@ class Climate : public EntityBase {
|
||||
*
|
||||
* @param callback The callback to call.
|
||||
*/
|
||||
void add_on_state_callback(std::function<void()> &&callback);
|
||||
void add_on_state_callback(std::function<void(Climate &)> &&callback);
|
||||
|
||||
/**
|
||||
* Add a callback for the climate device configuration; each time the configuration parameters of a climate device
|
||||
@@ -206,7 +206,7 @@ class Climate : public EntityBase {
|
||||
*
|
||||
* @param callback The callback to call.
|
||||
*/
|
||||
void add_on_control_callback(std::function<void()> &&callback);
|
||||
void add_on_control_callback(std::function<void(ClimateCall &)> &&callback);
|
||||
|
||||
/** Make a climate device control call, this is used to control the climate device, see the ClimateCall description
|
||||
* for more info.
|
||||
@@ -273,8 +273,8 @@ class Climate : public EntityBase {
|
||||
|
||||
void dump_traits_(const char *tag);
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
CallbackManager<void()> control_callback_{};
|
||||
CallbackManager<void(Climate &)> state_callback_{};
|
||||
CallbackManager<void(ClimateCall &)> control_callback_{};
|
||||
ESPPreferenceObject rtc_;
|
||||
optional<float> visual_min_temperature_override_{};
|
||||
optional<float> visual_max_temperature_override_{};
|
||||
|
@@ -44,11 +44,11 @@ async def register_climate_ir(var, config):
|
||||
|
||||
cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL]))
|
||||
cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT]))
|
||||
if CONF_SENSOR in config:
|
||||
sens = await cg.get_variable(config[CONF_SENSOR])
|
||||
if sensor_id := config.get(CONF_SENSOR):
|
||||
sens = await cg.get_variable(sensor_id)
|
||||
cg.add(var.set_sensor(sens))
|
||||
if CONF_RECEIVER_ID in config:
|
||||
receiver = await cg.get_variable(config[CONF_RECEIVER_ID])
|
||||
if receiver_id := config.get(CONF_RECEIVER_ID):
|
||||
receiver = await cg.get_variable(receiver_id)
|
||||
cg.add(receiver.register_listener(var))
|
||||
|
||||
transmitter = await cg.get_variable(config[CONF_TRANSMITTER_ID])
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user