mirror of
https://github.com/esphome/esphome.git
synced 2025-11-01 23:51:47 +00:00
Compare commits
226 Commits
jesserockz
...
2022.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
318b930e9f | ||
|
|
9296a078a7 | ||
|
|
5dc776e55f | ||
|
|
72d60f30f7 | ||
|
|
869743a742 | ||
|
|
7b03e07908 | ||
|
|
348f880e15 | ||
|
|
ead597d0fb | ||
|
|
afbf989715 | ||
|
|
01b62a16c3 | ||
|
|
c5eba04517 | ||
|
|
282313ab52 | ||
|
|
d274545e77 | ||
|
|
d3fda37615 | ||
|
|
cbe3092404 | ||
|
|
6dfe3039d0 | ||
|
|
d6009453df | ||
|
|
c81323ef91 | ||
|
|
961c27f1c2 | ||
|
|
fe4a14e6cc | ||
|
|
50848c2f4d | ||
|
|
d32633b3c7 | ||
|
|
b37739eec2 | ||
|
|
28f87dc804 | ||
|
|
41879e41e6 | ||
|
|
fc0a6546a2 | ||
|
|
ffd4280d6c | ||
|
|
db3b955b0f | ||
|
|
5516f65971 | ||
|
|
9471df0a1b | ||
|
|
6d39f64be7 | ||
|
|
b89d0a9a73 | ||
|
|
4bb779d9a5 | ||
|
|
386a5b6362 | ||
|
|
e32a999cd0 | ||
|
|
bfbc6a4bad | ||
|
|
8c9e0e552d | ||
|
|
8aaf9fd83f | ||
|
|
08057720b8 | ||
|
|
bfaa648837 | ||
|
|
d504daef91 | ||
|
|
b8d3ef2f49 | ||
|
|
3bf6320030 | ||
|
|
708b928c73 | ||
|
|
649366ff44 | ||
|
|
e5c9e87fad | ||
|
|
f3d9d707b6 | ||
|
|
090e10730c | ||
|
|
fbc84861c7 | ||
|
|
e763469af8 | ||
|
|
3c0c514e44 | ||
|
|
ed5e2dd332 | ||
|
|
09b7c6f550 | ||
|
|
df315a1f51 | ||
|
|
7ee4bb621c | ||
|
|
24874f4c3c | ||
|
|
c128880033 | ||
|
|
a66e94a0b0 | ||
|
|
56870ed4a8 | ||
|
|
3ac720df47 | ||
|
|
1bc757ad06 | ||
|
|
f72abc6f3d | ||
|
|
5ac88de985 | ||
|
|
0826b367d6 | ||
|
|
329bf861d6 | ||
|
|
9dcd3d18a0 | ||
|
|
db66cd88b6 | ||
|
|
86c205fe43 | ||
|
|
c6414138c7 | ||
|
|
36b355eb82 | ||
|
|
7be9291b13 | ||
|
|
ea9e75039b | ||
|
|
a5fb036011 | ||
|
|
e55506f9db | ||
|
|
50ec1d0445 | ||
|
|
3d5e1d8d91 | ||
|
|
db2128a344 | ||
|
|
21db43db06 | ||
|
|
5009b3029f | ||
|
|
57a029189c | ||
|
|
0cb715bb76 | ||
|
|
7d03823afd | ||
|
|
8e1c9f5042 | ||
|
|
980b7cda8f | ||
|
|
3a72dd5cb6 | ||
|
|
3178243811 | ||
|
|
d30e2f2a4f | ||
|
|
6226dae05c | ||
|
|
9c6a475a6e | ||
|
|
8294d10d5b | ||
|
|
67558bec47 | ||
|
|
84873d4074 | ||
|
|
58a0b28a39 | ||
|
|
b37d3a66cc | ||
|
|
7e495a5e27 | ||
|
|
c41547fd4a | ||
|
|
0d47d41c85 | ||
|
|
41a3a17456 | ||
|
|
cbbafbcca2 | ||
|
|
c75566b374 | ||
|
|
7279f1fcc1 | ||
|
|
d7432f7c10 | ||
|
|
b0a0a153f3 | ||
|
|
024632dbd0 | ||
|
|
0a545a28b9 | ||
|
|
0f2df59998 | ||
|
|
29a7d32f77 | ||
|
|
687a7e9b2f | ||
|
|
09e8782318 | ||
|
|
f2aea02210 | ||
|
|
194f922312 | ||
|
|
fea3c48098 | ||
|
|
c2f57baec2 | ||
|
|
f4a140e126 | ||
|
|
ab506b09fe | ||
|
|
87e1cdeedb | ||
|
|
81a36146ef | ||
|
|
7fa4a68a27 | ||
|
|
f1c5e2ef81 | ||
|
|
b526155cce | ||
|
|
62c3f301e7 | ||
|
|
38cb988809 | ||
|
|
b976ac54c8 | ||
|
|
78026e766f | ||
|
|
b4cd8d21a5 | ||
|
|
7552893311 | ||
|
|
21c896d8f8 | ||
|
|
4b7fe202ec | ||
|
|
9f4519210f | ||
|
|
b0506afa5b | ||
|
|
8cbb379898 | ||
|
|
b226215593 | ||
|
|
19970729a9 | ||
|
|
d2ebfd2833 | ||
|
|
bd782fc828 | ||
|
|
23560e608c | ||
|
|
f1377b560e | ||
|
|
72108684ea | ||
|
|
c6adaaea97 | ||
|
|
91999a38ca | ||
|
|
b34eed125d | ||
|
|
2abe09529a | ||
|
|
9aaaf4dd4b | ||
|
|
cbfbcf7f1b | ||
|
|
c7651dc40d | ||
|
|
eda1c471ad | ||
|
|
c7ef18fbc4 | ||
|
|
901ec918b1 | ||
|
|
6bdae55ee1 | ||
|
|
dfb96e4b7f | ||
|
|
ff2c316b18 | ||
|
|
5be52f71f9 | ||
|
|
42873dd37c | ||
|
|
f93e7d4e3a | ||
|
|
bbcd523967 | ||
|
|
68cbe58d00 | ||
|
|
115bca98f1 | ||
|
|
ed0b34b2fe | ||
|
|
ab34401421 | ||
|
|
eed0c18d65 | ||
|
|
e5a38ce748 | ||
|
|
7d9d9fcf36 | ||
|
|
f0aba6ceb2 | ||
|
|
ab07ee57c6 | ||
|
|
eae3d72a4d | ||
|
|
7b8d826704 | ||
|
|
e7baa42e63 | ||
|
|
2f32833a22 | ||
|
|
f6935a4b4b | ||
|
|
332c9e891b | ||
|
|
b91ee4847f | ||
|
|
625463d871 | ||
|
|
6433a01e07 | ||
|
|
56cc31e8e7 | ||
|
|
3af297aa76 | ||
|
|
996ec59d28 | ||
|
|
95593eeeab | ||
|
|
dad244fb7a | ||
|
|
adb5d27d95 | ||
|
|
8456a8cecb | ||
|
|
b9f66373c1 | ||
|
|
9ac365feef | ||
|
|
43bbd58a44 | ||
|
|
7feffa64f3 | ||
|
|
ea0977abb4 | ||
|
|
4c83dc7c28 | ||
|
|
e10ab1da78 | ||
|
|
1b0e60374b | ||
|
|
3a760fbb44 | ||
|
|
6ef57a2973 | ||
|
|
3e9c7f2e9f | ||
|
|
430598b7a1 | ||
|
|
91611b09b4 | ||
|
|
ecd115851f | ||
|
|
4a1e50fed1 | ||
|
|
d6d037047b | ||
|
|
b5734c2b20 | ||
|
|
723fb7eaac | ||
|
|
63a9acaa19 | ||
|
|
0524f8c677 | ||
|
|
70b62f272e | ||
|
|
f0089b7940 | ||
|
|
4b44280d53 | ||
|
|
f045382d20 | ||
|
|
db3fa1ade7 | ||
|
|
f83950fd75 | ||
|
|
4dd1bf920d | ||
|
|
98755f3621 | ||
|
|
c3a8a044b9 | ||
|
|
15b5ea43a7 | ||
|
|
ec683fc227 | ||
|
|
d4e65eb82a | ||
|
|
10c6601b0a | ||
|
|
73940bc1bd | ||
|
|
9b7fb829f9 | ||
|
|
c51d8c9021 | ||
|
|
d8a6dfe5ce | ||
|
|
5f7cef0b06 | ||
|
|
48ff2ffc68 | ||
|
|
b3b9ccd314 | ||
|
|
e63c7b483b | ||
|
|
f57980b069 | ||
|
|
7006aa0d2a | ||
|
|
8051c1ca99 | ||
|
|
a779592414 | ||
|
|
112215848d |
10
.clang-tidy
10
.clang-tidy
@@ -68,6 +68,8 @@ Checks: >-
|
||||
-modernize-use-nodiscard,
|
||||
-mpi-*,
|
||||
-objc-*,
|
||||
-readability-braces-around-statements,
|
||||
-readability-const-return-type,
|
||||
-readability-convert-member-functions-to-static,
|
||||
-readability-else-after-return,
|
||||
-readability-function-cognitive-complexity,
|
||||
@@ -75,6 +77,10 @@ Checks: >-
|
||||
-readability-isolate-declaration,
|
||||
-readability-magic-numbers,
|
||||
-readability-make-member-function-const,
|
||||
-readability-named-parameter,
|
||||
-readability-qualified-auto,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-redundant-member-init,
|
||||
-readability-redundant-string-init,
|
||||
-readability-uppercase-literal-suffix,
|
||||
-readability-use-anyofallof,
|
||||
@@ -108,8 +114,6 @@ CheckOptions:
|
||||
value: 'make_unique'
|
||||
- key: modernize-make-unique.MakeSmartPtrFunctionHeader
|
||||
value: 'esphome/core/helpers.h'
|
||||
- key: readability-braces-around-statements.ShortStatementLines
|
||||
value: 2
|
||||
- key: readability-identifier-naming.LocalVariableCase
|
||||
value: 'lower_case'
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
@@ -156,5 +160,3 @@ CheckOptions:
|
||||
value: 'lower_case'
|
||||
- key: readability-identifier-naming.VirtualMethodSuffix
|
||||
value: ''
|
||||
- key: readability-qualified-auto.AddConstToQualified
|
||||
value: 0
|
||||
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -80,7 +80,7 @@ jobs:
|
||||
uses: actions/setup-python@v2
|
||||
id: python
|
||||
with:
|
||||
python-version: '3.8'
|
||||
python-version: '3.7'
|
||||
|
||||
- name: Cache virtualenv
|
||||
uses: actions/cache@v2
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -137,18 +137,18 @@ jobs:
|
||||
--build-type "${{ matrix.build_type }}" \
|
||||
manifest
|
||||
|
||||
deploy-ha-addon-repo:
|
||||
deploy-hassio-repo:
|
||||
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [deploy-docker]
|
||||
steps:
|
||||
- env:
|
||||
TOKEN: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
|
||||
TOKEN: ${{ secrets.DEPLOY_HASSIO_TOKEN }}
|
||||
run: |
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
curl \
|
||||
-u ":$TOKEN" \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/esphome/home-assistant-addon/actions/workflows/bump-version.yml/dispatches \
|
||||
https://api.github.com/repos/esphome/hassio/actions/workflows/bump-version.yml/dispatches \
|
||||
-d "{\"ref\":\"main\",\"inputs\":{\"version\":\"$TAG\"}}"
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -77,7 +77,6 @@ venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
venv-*/
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
@@ -3,4 +3,4 @@ ports:
|
||||
onOpen: open-preview
|
||||
tasks:
|
||||
- before: pyenv local $(pyenv version | grep '^3\.' | cut -d ' ' -f 1) && script/setup
|
||||
command: python -m esphome dashboard config
|
||||
command: python -m esphome config dashboard
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/ambv/black
|
||||
rev: 22.1.0
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: black
|
||||
args:
|
||||
@@ -10,7 +10,7 @@ repos:
|
||||
- --quiet
|
||||
files: ^((esphome|script|tests)/.+)?[^/]+\.py$
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 4.0.1
|
||||
rev: 3.8.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
@@ -25,8 +25,3 @@ repos:
|
||||
- --branch=dev
|
||||
- --branch=release
|
||||
- --branch=beta
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.31.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py38-plus]
|
||||
|
||||
13
CODEOWNERS
13
CODEOWNERS
@@ -19,7 +19,6 @@ esphome/components/airthings_wave_mini/* @ncareau
|
||||
esphome/components/airthings_wave_plus/* @jeromelaban
|
||||
esphome/components/am43/* @buxtronix
|
||||
esphome/components/am43/cover/* @buxtronix
|
||||
esphome/components/analog_threshold/* @ianchi
|
||||
esphome/components/animation/* @syndlex
|
||||
esphome/components/anova/* @buxtronix
|
||||
esphome/components/api/* @OttoWinter
|
||||
@@ -55,7 +54,6 @@ esphome/components/dfplayer/* @glmnet
|
||||
esphome/components/dht/* @OttoWinter
|
||||
esphome/components/ds1307/* @badbadc0ffee
|
||||
esphome/components/dsmr/* @glmnet @zuidwijk
|
||||
esphome/components/ektf2232/* @jesserockz
|
||||
esphome/components/esp32/* @esphome/core
|
||||
esphome/components/esp32_ble/* @jesserockz
|
||||
esphome/components/esp32_ble_server/* @jesserockz
|
||||
@@ -90,12 +88,9 @@ esphome/components/json/* @OttoWinter
|
||||
esphome/components/kalman_combinator/* @Cat-Ion
|
||||
esphome/components/ledc/* @OttoWinter
|
||||
esphome/components/light/* @esphome/core
|
||||
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
|
||||
esphome/components/lock/* @esphome/core
|
||||
esphome/components/logger/* @esphome/core
|
||||
esphome/components/ltr390/* @sjtrny
|
||||
esphome/components/max7219digit/* @rspaargaren
|
||||
esphome/components/max9611/* @mckaymatthew
|
||||
esphome/components/mcp23008/* @jesserockz
|
||||
esphome/components/mcp23017/* @jesserockz
|
||||
esphome/components/mcp23s08/* @SenexCrenshaw @jesserockz
|
||||
@@ -112,12 +107,10 @@ esphome/components/mdns/* @esphome/core
|
||||
esphome/components/midea/* @dudanov
|
||||
esphome/components/midea_ir/* @dudanov
|
||||
esphome/components/mitsubishi/* @RubyBailey
|
||||
esphome/components/mlx90393/* @functionpointer
|
||||
esphome/components/modbus_controller/* @martgras
|
||||
esphome/components/modbus_controller/binary_sensor/* @martgras
|
||||
esphome/components/modbus_controller/number/* @martgras
|
||||
esphome/components/modbus_controller/output/* @martgras
|
||||
esphome/components/modbus_controller/select/* @martgras @stegm
|
||||
esphome/components/modbus_controller/sensor/* @martgras
|
||||
esphome/components/modbus_controller/switch/* @martgras
|
||||
esphome/components/modbus_controller/text_sensor/* @martgras
|
||||
@@ -143,9 +136,6 @@ esphome/components/preferences/* @esphome/core
|
||||
esphome/components/psram/* @esphome/core
|
||||
esphome/components/pulse_meter/* @stevebaxter
|
||||
esphome/components/pvvx_mithermometer/* @pasiz
|
||||
esphome/components/qr_code/* @wjtje
|
||||
esphome/components/radon_eye_ble/* @jeffeb3
|
||||
esphome/components/radon_eye_rd200/* @jeffeb3
|
||||
esphome/components/rc522/* @glmnet
|
||||
esphome/components/rc522_i2c/* @glmnet
|
||||
esphome/components/rc522_spi/* @glmnet
|
||||
@@ -197,7 +187,6 @@ esphome/components/tmp102/* @timsavage
|
||||
esphome/components/tmp117/* @Azimath
|
||||
esphome/components/tof10120/* @wstrzalka
|
||||
esphome/components/toshiba/* @kbx81
|
||||
esphome/components/touchscreen/* @jesserockz
|
||||
esphome/components/tsl2591/* @wjcarpenter
|
||||
esphome/components/tuya/binary_sensor/* @jesserockz
|
||||
esphome/components/tuya/climate/* @jesserockz
|
||||
@@ -208,10 +197,8 @@ esphome/components/tuya/text_sensor/* @dentra
|
||||
esphome/components/uart/* @esphome/core
|
||||
esphome/components/ultrasonic/* @OttoWinter
|
||||
esphome/components/version/* @esphome/core
|
||||
esphome/components/wake_on_lan/* @willwill2will54
|
||||
esphome/components/web_server_base/* @OttoWinter
|
||||
esphome/components/whirlpool/* @glmnet
|
||||
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
|
||||
esphome/components/xiaomi_mhoc303/* @drug123
|
||||
esphome/components/xiaomi_mhoc401/* @vevsvevs
|
||||
esphome/components/xpt2046/* @numo68
|
||||
|
||||
@@ -4,5 +4,4 @@ include requirements.txt
|
||||
include esphome/dashboard/templates/*.html
|
||||
recursive-include esphome/dashboard/static *.ico *.js *.css *.woff* LICENSE
|
||||
recursive-include esphome *.cpp *.h *.tcc
|
||||
recursive-include esphome *.py.script
|
||||
recursive-include esphome LICENSE.txt
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
# One of "docker", "hassio"
|
||||
ARG BASEIMGTYPE=docker
|
||||
|
||||
# https://github.com/hassio-addons/addon-debian-base/releases
|
||||
FROM ghcr.io/hassio-addons/debian-base/amd64:5.2.3 AS base-hassio-amd64
|
||||
FROM ghcr.io/hassio-addons/debian-base/aarch64:5.2.3 AS base-hassio-arm64
|
||||
FROM ghcr.io/hassio-addons/debian-base/armv7:5.2.3 AS base-hassio-armv7
|
||||
# https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye
|
||||
FROM debian:bullseye-20220125-slim AS base-docker-amd64
|
||||
FROM debian:bullseye-20220125-slim AS base-docker-arm64
|
||||
FROM debian:bullseye-20220125-slim AS base-docker-armv7
|
||||
FROM debian:bullseye-20211220-slim AS base-docker-amd64
|
||||
FROM debian:bullseye-20211220-slim AS base-docker-arm64
|
||||
FROM debian:bullseye-20211220-slim AS base-docker-armv7
|
||||
|
||||
# Use TARGETARCH/TARGETVARIANT defined by docker
|
||||
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
|
||||
@@ -25,7 +23,7 @@ RUN \
|
||||
python3=3.9.2-3 \
|
||||
python3-pip=20.3.4-4 \
|
||||
python3-setuptools=52.0.0-4 \
|
||||
python3-pil=8.1.2+dfsg-0.3+deb11u1 \
|
||||
python3-pil=8.1.2+dfsg-0.3 \
|
||||
python3-cryptography=3.3.2-1 \
|
||||
iputils-ping=3:20210202-1 \
|
||||
git=1:2.30.2-1 \
|
||||
@@ -45,7 +43,7 @@ RUN \
|
||||
# Ubuntu python3-pip is missing wheel
|
||||
pip3 install --no-cache-dir \
|
||||
wheel==0.37.1 \
|
||||
platformio==5.2.5 \
|
||||
platformio==5.2.4 \
|
||||
# Change some platformio settings
|
||||
&& platformio settings set enable_telemetry No \
|
||||
&& platformio settings set check_libraries_interval 1000000 \
|
||||
@@ -54,16 +52,16 @@ RUN \
|
||||
&& mkdir -p /piolibs
|
||||
|
||||
|
||||
|
||||
# ======================= docker-type image =======================
|
||||
FROM base AS docker
|
||||
|
||||
# First install requirements to leverage caching when requirements don't change
|
||||
COPY requirements.txt requirements_optional.txt docker/platformio_install_deps.py platformio.ini /
|
||||
RUN \
|
||||
pip3 install --no-cache-dir -r /requirements.txt -r /requirements_optional.txt \
|
||||
&& /platformio_install_deps.py /platformio.ini
|
||||
|
||||
|
||||
# ======================= docker-type image =======================
|
||||
FROM base AS docker
|
||||
|
||||
# Copy esphome and install
|
||||
COPY . /esphome
|
||||
RUN pip3 install --no-cache-dir --no-use-pep517 -e /esphome
|
||||
@@ -95,7 +93,7 @@ RUN \
|
||||
apt-get update \
|
||||
# Use pinned versions so that we get updates with build caching
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
nginx-light=1.18.0-6.1 \
|
||||
nginx=1.18.0-6.1 \
|
||||
&& rm -rf \
|
||||
/tmp/* \
|
||||
/var/{cache,log}/* \
|
||||
@@ -104,7 +102,13 @@ RUN \
|
||||
ARG BUILD_VERSION=dev
|
||||
|
||||
# Copy root filesystem
|
||||
COPY docker/ha-addon-rootfs/ /
|
||||
COPY docker/hassio-rootfs/ /
|
||||
|
||||
# First install requirements to leverage caching when requirements don't change
|
||||
COPY requirements.txt requirements_optional.txt docker/platformio_install_deps.py platformio.ini /
|
||||
RUN \
|
||||
pip3 install --no-cache-dir -r /requirements.txt -r /requirements_optional.txt \
|
||||
&& /platformio_install_deps.py /platformio.ini
|
||||
|
||||
# Copy esphome and install
|
||||
COPY . /esphome
|
||||
@@ -143,8 +147,10 @@ RUN \
|
||||
/var/{cache,log}/* \
|
||||
/var/lib/apt/lists/*
|
||||
|
||||
COPY requirements_test.txt /
|
||||
RUN pip3 install --no-cache-dir -r /requirements_test.txt
|
||||
COPY requirements.txt requirements_optional.txt requirements_test.txt docker/platformio_install_deps.py platformio.ini /
|
||||
RUN \
|
||||
pip3 install --no-cache-dir -r /requirements.txt -r /requirements_optional.txt -r /requirements_test.txt \
|
||||
&& /platformio_install_deps.py /platformio.ini
|
||||
|
||||
VOLUME ["/esphome"]
|
||||
WORKDIR /esphome
|
||||
|
||||
@@ -10,7 +10,7 @@ server {
|
||||
ssl_certificate_key /ssl/%%keyfile%%;
|
||||
|
||||
# Clear Hass.io Ingress header
|
||||
proxy_set_header X-HA-Ingress "";
|
||||
proxy_set_header X-Hassio-Ingress "";
|
||||
|
||||
# Redirect http requests to https on the same port.
|
||||
# https://rageagainstshell.com/2016/11/redirect-http-to-https-on-the-same-port-in-nginx/
|
||||
@@ -4,7 +4,7 @@ server {
|
||||
include /etc/nginx/includes/server_params.conf;
|
||||
include /etc/nginx/includes/proxy_params.conf;
|
||||
# Clear Hass.io Ingress header
|
||||
proxy_set_header X-HA-Ingress "";
|
||||
proxy_set_header X-Hassio-Ingress "";
|
||||
|
||||
location / {
|
||||
proxy_pass http://esphome;
|
||||
@@ -3,8 +3,8 @@ server {
|
||||
|
||||
include /etc/nginx/includes/server_params.conf;
|
||||
include /etc/nginx/includes/proxy_params.conf;
|
||||
# Set Home Assistant Ingress header
|
||||
proxy_set_header X-HA-Ingress "YES";
|
||||
# Set Hass.io Ingress header
|
||||
proxy_set_header X-Hassio-Ingress "YES";
|
||||
|
||||
location / {
|
||||
# Only allow from Hass.io supervisor
|
||||
@@ -4,7 +4,7 @@
|
||||
# Runs the ESPHome dashboard
|
||||
# ==============================================================================
|
||||
|
||||
export ESPHOME_IS_HA_ADDON=true
|
||||
export ESPHOME_IS_HASSIO=true
|
||||
|
||||
if bashio::config.true 'leave_front_door_open'; then
|
||||
export DISABLE_HA_AUTHENTICATION=true
|
||||
@@ -32,4 +32,4 @@ export PLATFORMIO_CACHE_DIR="${pio_cache_base}/cache"
|
||||
export PLATFORMIO_GLOBALLIB_DIR=/piolibs
|
||||
|
||||
bashio::log.info "Starting ESPHome dashboard..."
|
||||
exec esphome dashboard /config/esphome --socket /var/run/esphome.sock --ha-addon
|
||||
exec esphome dashboard /config/esphome --socket /var/run/esphome.sock --hassio
|
||||
@@ -661,7 +661,7 @@ def parse_args(argv):
|
||||
"--open-ui", help="Open the dashboard UI in a browser.", action="store_true"
|
||||
)
|
||||
parser_dashboard.add_argument(
|
||||
"--ha-addon", help=argparse.SUPPRESS, action="store_true"
|
||||
"--hassio", help=argparse.SUPPRESS, action="store_true"
|
||||
)
|
||||
parser_dashboard.add_argument(
|
||||
"--socket", help="Make the dashboard serve under a unix socket", type=str
|
||||
@@ -778,10 +778,10 @@ def run_esphome(argv):
|
||||
_LOGGER.warning("Please instead use:")
|
||||
_LOGGER.warning(" esphome %s", " ".join(args.deprecated_argv_suggestion))
|
||||
|
||||
if sys.version_info < (3, 8, 0):
|
||||
if sys.version_info < (3, 7, 0):
|
||||
_LOGGER.error(
|
||||
"You're running ESPHome with Python <3.8. ESPHome is no longer compatible "
|
||||
"with this Python version. Please reinstall ESPHome with Python 3.8+"
|
||||
"You're running ESPHome with Python <3.7. ESPHome is no longer compatible "
|
||||
"with this Python version. Please reinstall ESPHome with Python 3.7+"
|
||||
)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ from esphome.cpp_types import ( # noqa
|
||||
uint32,
|
||||
uint64,
|
||||
int32,
|
||||
int64,
|
||||
const_char_ptr,
|
||||
NAN,
|
||||
esphome_ns,
|
||||
@@ -82,5 +81,4 @@ from esphome.cpp_types import ( # noqa
|
||||
InternalGPIOPin,
|
||||
gpio_Flags,
|
||||
EntityCategory,
|
||||
Parented,
|
||||
)
|
||||
|
||||
@@ -52,10 +52,10 @@ uint32_t IRAM_ATTR HOT AcDimmerDataStore::timer_intr(uint32_t now) {
|
||||
this->gate_pin.digital_write(false);
|
||||
}
|
||||
|
||||
if (time_since_zc < this->enable_time_us) {
|
||||
if (time_since_zc < this->enable_time_us)
|
||||
// Next event is enable, return time until that event
|
||||
return this->enable_time_us - time_since_zc;
|
||||
} else if (time_since_zc < disable_time_us) {
|
||||
else if (time_since_zc < disable_time_us) {
|
||||
// Next event is disable, return time until that event
|
||||
return this->disable_time_us - time_since_zc;
|
||||
}
|
||||
@@ -74,10 +74,9 @@ uint32_t IRAM_ATTR HOT timer_interrupt() {
|
||||
uint32_t min_dt_us = 1000;
|
||||
uint32_t now = micros();
|
||||
for (auto *dimmer : all_dimmers) {
|
||||
if (dimmer == nullptr) {
|
||||
if (dimmer == nullptr)
|
||||
// no more dimmers
|
||||
break;
|
||||
}
|
||||
uint32_t res = dimmer->timer_intr(now);
|
||||
if (res != 0 && res < min_dt_us)
|
||||
min_dt_us = res;
|
||||
@@ -213,13 +212,12 @@ void AcDimmer::dump_config() {
|
||||
LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_);
|
||||
ESP_LOGCONFIG(TAG, " Min Power: %.1f%%", this->store_.min_power / 10.0f);
|
||||
ESP_LOGCONFIG(TAG, " Init with half cycle: %s", YESNO(this->init_with_half_cycle_));
|
||||
if (method_ == DIM_METHOD_LEADING_PULSE) {
|
||||
if (method_ == DIM_METHOD_LEADING_PULSE)
|
||||
ESP_LOGCONFIG(TAG, " Method: leading pulse");
|
||||
} else if (method_ == DIM_METHOD_LEADING) {
|
||||
else if (method_ == DIM_METHOD_LEADING)
|
||||
ESP_LOGCONFIG(TAG, " Method: leading");
|
||||
} else {
|
||||
else
|
||||
ESP_LOGCONFIG(TAG, " Method: trailing");
|
||||
}
|
||||
|
||||
LOG_FLOAT_OUTPUT(this);
|
||||
ESP_LOGV(TAG, " Estimated Frequency: %.3fHz", 1e6f / this->store_.cycle_time_us / 2);
|
||||
|
||||
@@ -13,6 +13,7 @@ class AdalightLightEffect : public light::AddressableLightEffect, public uart::U
|
||||
public:
|
||||
AdalightLightEffect(const std::string &name);
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void apply(light::AddressableLight &it, const Color ¤t_color) override;
|
||||
@@ -29,6 +30,7 @@ class AdalightLightEffect : public light::AddressableLightEffect, public uart::U
|
||||
void blank_all_leds_(light::AddressableLight &it);
|
||||
Frame parse_frame_(light::AddressableLight &it);
|
||||
|
||||
protected:
|
||||
uint32_t last_ack_{0};
|
||||
uint32_t last_byte_{0};
|
||||
uint32_t last_reset_{0};
|
||||
|
||||
@@ -15,11 +15,6 @@ namespace esphome {
|
||||
namespace adc {
|
||||
|
||||
static const char *const TAG = "adc";
|
||||
// 13 bits for S3 / 12 bit for all other esp32 variants
|
||||
// create a const to avoid the repated cast to enum
|
||||
#ifdef USE_ESP32
|
||||
static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
|
||||
#endif
|
||||
|
||||
void ADCSensor::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
|
||||
@@ -28,14 +23,14 @@ void ADCSensor::setup() {
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP32
|
||||
adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
if (!autorange_) {
|
||||
adc1_config_channel_atten(channel_, attenuation_);
|
||||
}
|
||||
|
||||
// load characteristics for each attenuation
|
||||
for (int i = 0; i < (int) ADC_ATTEN_MAX; i++) {
|
||||
auto cal_value = esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
|
||||
auto cal_value = esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t) i, ADC_WIDTH_BIT_12,
|
||||
1100, // default vref
|
||||
&cal_characteristics_[i]);
|
||||
switch (cal_value) {
|
||||
@@ -70,9 +65,9 @@ void ADCSensor::dump_config() {
|
||||
|
||||
#ifdef USE_ESP32
|
||||
LOG_PIN(" Pin: ", pin_);
|
||||
if (autorange_) {
|
||||
if (autorange_)
|
||||
ESP_LOGCONFIG(TAG, " Attenuation: auto");
|
||||
} else {
|
||||
else
|
||||
switch (this->attenuation_) {
|
||||
case ADC_ATTEN_DB_0:
|
||||
ESP_LOGCONFIG(TAG, " Attenuation: 0db (max 1.1V)");
|
||||
@@ -89,7 +84,6 @@ void ADCSensor::dump_config() {
|
||||
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // USE_ESP32
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,6 @@ ADCSensor = adc_ns.class_(
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(
|
||||
ADCSensor,
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
accuracy_decimals=2,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
@@ -141,6 +140,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ADCSensor),
|
||||
cv.Required(CONF_PIN): validate_adc_pin,
|
||||
cv.Optional(CONF_RAW, default=False): cv.boolean,
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||
|
||||
@@ -52,7 +52,6 @@ ADS1115Sensor = ads1115_ns.class_(
|
||||
CONF_ADS1115_ID = "ads1115_id"
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
ADS1115Sensor,
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
accuracy_decimals=3,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
@@ -60,6 +59,7 @@ CONFIG_SCHEMA = (
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ADS1115Sensor),
|
||||
cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component),
|
||||
cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"),
|
||||
cv.Required(CONF_GAIN): validate_gain,
|
||||
|
||||
@@ -24,7 +24,7 @@ void AirthingsWaveMini::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
|
||||
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
this->handle_ = 0;
|
||||
auto *chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
|
||||
auto chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
|
||||
if (chr == nullptr) {
|
||||
ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", service_uuid_.to_string().c_str(),
|
||||
sensors_data_characteristic_uuid_.to_string().c_str());
|
||||
@@ -56,7 +56,7 @@ void AirthingsWaveMini::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
|
||||
}
|
||||
|
||||
void AirthingsWaveMini::read_sensors_(uint8_t *raw_value, uint16_t value_len) {
|
||||
auto *value = (WaveMiniReadings *) raw_value;
|
||||
auto value = (WaveMiniReadings *) raw_value;
|
||||
|
||||
if (sizeof(WaveMiniReadings) <= value_len) {
|
||||
this->humidity_sensor_->publish_state(value->humidity / 100.0f);
|
||||
|
||||
@@ -24,7 +24,7 @@ void AirthingsWavePlus::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
|
||||
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
this->handle_ = 0;
|
||||
auto *chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
|
||||
auto chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
|
||||
if (chr == nullptr) {
|
||||
ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", service_uuid_.to_string().c_str(),
|
||||
sensors_data_characteristic_uuid_.to_string().c_str());
|
||||
@@ -56,7 +56,7 @@ void AirthingsWavePlus::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
|
||||
}
|
||||
|
||||
void AirthingsWavePlus::read_sensors_(uint8_t *raw_value, uint16_t value_len) {
|
||||
auto *value = (WavePlusReadings *) raw_value;
|
||||
auto value = (WavePlusReadings *) raw_value;
|
||||
|
||||
if (sizeof(WavePlusReadings) <= value_len) {
|
||||
ESP_LOGD(TAG, "version = %d", value->version);
|
||||
|
||||
@@ -19,14 +19,12 @@ uint16_t crc_16(uint8_t *ptr, uint8_t length) {
|
||||
//------------------------------
|
||||
while (length--) {
|
||||
crc ^= *ptr++;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < 8; i++)
|
||||
if ((crc & 0x01) != 0) {
|
||||
crc >>= 1;
|
||||
crc ^= 0xA001;
|
||||
} else {
|
||||
} else
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
|
||||
auto chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
|
||||
if (chr == nullptr) {
|
||||
if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
|
||||
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.",
|
||||
@@ -75,14 +75,13 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
|
||||
|
||||
if (this->current_sensor_ > 0) {
|
||||
if (this->illuminance_ != nullptr) {
|
||||
auto *packet = this->encoder_->get_light_level_request();
|
||||
auto packet = this->encoder_->get_light_level_request();
|
||||
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
|
||||
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
|
||||
status);
|
||||
}
|
||||
}
|
||||
this->current_sensor_ = 0;
|
||||
}
|
||||
@@ -100,7 +99,7 @@ void Am43::update() {
|
||||
}
|
||||
if (this->current_sensor_ == 0) {
|
||||
if (this->battery_ != nullptr) {
|
||||
auto *packet = this->encoder_->get_battery_level_request();
|
||||
auto packet = this->encoder_->get_battery_level_request();
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
|
||||
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
|
||||
@@ -5,7 +5,7 @@ from esphome.const import CONF_ID, CONF_PIN
|
||||
|
||||
CODEOWNERS = ["@buxtronix"]
|
||||
DEPENDENCIES = ["ble_client"]
|
||||
AUTO_LOAD = ["am43", "sensor"]
|
||||
AUTO_LOAD = ["am43"]
|
||||
|
||||
CONF_INVERT_POSITION = "invert_position"
|
||||
|
||||
|
||||
@@ -25,16 +25,15 @@ void Am43Component::setup() {
|
||||
|
||||
void Am43Component::loop() {
|
||||
if (this->node_state == espbt::ClientState::ESTABLISHED && !this->logged_in_) {
|
||||
auto *packet = this->encoder_->get_send_pin_request(this->pin_);
|
||||
auto packet = this->encoder_->get_send_pin_request(this->pin_);
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
|
||||
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
ESP_LOGI(TAG, "[%s] Logging into AM43", this->get_name().c_str());
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] Error writing set_pin to device, error = %d", this->get_name().c_str(), status);
|
||||
} else {
|
||||
else
|
||||
this->logged_in_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +51,7 @@ void Am43Component::control(const CoverCall &call) {
|
||||
return;
|
||||
}
|
||||
if (call.get_stop()) {
|
||||
auto *packet = this->encoder_->get_stop_request();
|
||||
auto packet = this->encoder_->get_stop_request();
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
|
||||
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
@@ -64,7 +63,7 @@ void Am43Component::control(const CoverCall &call) {
|
||||
|
||||
if (this->invert_position_)
|
||||
pos = 1 - pos;
|
||||
auto *packet = this->encoder_->get_set_position_request(100 - (uint8_t)(pos * 100));
|
||||
auto packet = this->encoder_->get_set_position_request(100 - (uint8_t)(pos * 100));
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
|
||||
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
@@ -81,7 +80,7 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
|
||||
auto chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
|
||||
if (chr == nullptr) {
|
||||
if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
|
||||
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.", this->get_name().c_str());
|
||||
@@ -121,7 +120,7 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
if (this->decoder_->has_pin_response()) {
|
||||
if (this->decoder_->pin_ok_) {
|
||||
ESP_LOGI(TAG, "[%s] AM43 pin accepted.", this->get_name().c_str());
|
||||
auto *packet = this->encoder_->get_position_request();
|
||||
auto packet = this->encoder_->get_position_request();
|
||||
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
|
||||
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
CODEOWNERS = ["@ianchi"]
|
||||
@@ -1,40 +0,0 @@
|
||||
#include "analog_threshold_binary_sensor.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace analog_threshold {
|
||||
|
||||
static const char *const TAG = "analog_threshold.binary_sensor";
|
||||
|
||||
void AnalogThresholdBinarySensor::setup() {
|
||||
float sensor_value = this->sensor_->get_state();
|
||||
|
||||
// TRUE state is defined to be when sensor is >= threshold
|
||||
// so when undefined sensor value initialize to FALSE
|
||||
if (std::isnan(sensor_value)) {
|
||||
this->publish_initial_state(false);
|
||||
} else {
|
||||
this->publish_initial_state(sensor_value >= (this->lower_threshold_ + this->upper_threshold_) / 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogThresholdBinarySensor::set_sensor(sensor::Sensor *analog_sensor) {
|
||||
this->sensor_ = analog_sensor;
|
||||
|
||||
this->sensor_->add_on_state_callback([this](float sensor_value) {
|
||||
// if there is an invalid sensor reading, ignore the change and keep the current state
|
||||
if (!std::isnan(sensor_value)) {
|
||||
this->publish_state(sensor_value >= (this->state ? this->lower_threshold_ : this->upper_threshold_));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AnalogThresholdBinarySensor::dump_config() {
|
||||
LOG_BINARY_SENSOR("", "Analog Threshold Binary Sensor", this);
|
||||
LOG_SENSOR(" ", "Sensor", this->sensor_);
|
||||
ESP_LOGCONFIG(TAG, " Upper threshold: %.11f", this->upper_threshold_);
|
||||
ESP_LOGCONFIG(TAG, " Lower threshold: %.11f", this->lower_threshold_);
|
||||
}
|
||||
|
||||
} // namespace analog_threshold
|
||||
} // namespace esphome
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace analog_threshold {
|
||||
|
||||
class AnalogThresholdBinarySensor : public Component, public binary_sensor::BinarySensor {
|
||||
public:
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
|
||||
void set_sensor(sensor::Sensor *analog_sensor);
|
||||
void set_upper_threshold(float threshold) { this->upper_threshold_ = threshold; }
|
||||
void set_lower_threshold(float threshold) { this->lower_threshold_ = threshold; }
|
||||
|
||||
protected:
|
||||
sensor::Sensor *sensor_{nullptr};
|
||||
|
||||
float upper_threshold_;
|
||||
float lower_threshold_;
|
||||
};
|
||||
|
||||
} // namespace analog_threshold
|
||||
} // namespace esphome
|
||||
@@ -1,44 +0,0 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor, sensor
|
||||
from esphome.const import (
|
||||
CONF_SENSOR_ID,
|
||||
CONF_THRESHOLD,
|
||||
)
|
||||
|
||||
analog_threshold_ns = cg.esphome_ns.namespace("analog_threshold")
|
||||
|
||||
AnalogThresholdBinarySensor = analog_threshold_ns.class_(
|
||||
"AnalogThresholdBinarySensor", binary_sensor.BinarySensor, cg.Component
|
||||
)
|
||||
|
||||
CONF_UPPER = "upper"
|
||||
CONF_LOWER = "lower"
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AnalogThresholdBinarySensor),
|
||||
cv.Required(CONF_SENSOR_ID): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_THRESHOLD): cv.Any(
|
||||
cv.float_,
|
||||
cv.Schema(
|
||||
{cv.Required(CONF_UPPER): cv.float_, cv.Required(CONF_LOWER): cv.float_}
|
||||
),
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await binary_sensor.new_binary_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
|
||||
sens = await cg.get_variable(config[CONF_SENSOR_ID])
|
||||
cg.add(var.set_sensor(sens))
|
||||
|
||||
if isinstance(config[CONF_THRESHOLD], float):
|
||||
cg.add(var.set_upper_threshold(config[CONF_THRESHOLD]))
|
||||
cg.add(var.set_lower_threshold(config[CONF_THRESHOLD]))
|
||||
else:
|
||||
cg.add(var.set_upper_threshold(config[CONF_THRESHOLD][CONF_UPPER]))
|
||||
cg.add(var.set_lower_threshold(config[CONF_THRESHOLD][CONF_LOWER]))
|
||||
@@ -76,6 +76,8 @@ async def to_code(config):
|
||||
pos = 0
|
||||
for frameIndex in range(frames):
|
||||
image.seek(frameIndex)
|
||||
if CONF_RESIZE in config:
|
||||
image.thumbnail(config[CONF_RESIZE])
|
||||
frame = image.convert("RGB")
|
||||
if CONF_RESIZE in config:
|
||||
frame = frame.resize([width, height])
|
||||
|
||||
@@ -40,7 +40,7 @@ void Anova::control(const ClimateCall &call) {
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
|
||||
}
|
||||
if (call.get_target_temperature().has_value()) {
|
||||
auto *pkt = this->codec_->get_set_target_temp_request(*call.get_target_temperature());
|
||||
auto pkt = this->codec_->get_set_target_temp_request(*call.get_target_temperature());
|
||||
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
|
||||
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status)
|
||||
@@ -57,7 +57,7 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
auto *chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
|
||||
auto chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
|
||||
if (chr == nullptr) {
|
||||
ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", this->get_name().c_str());
|
||||
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str());
|
||||
@@ -114,10 +114,9 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
|
||||
auto status =
|
||||
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, pkt->length,
|
||||
pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
if (status)
|
||||
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
|
||||
status);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -134,7 +133,7 @@ void Anova::update() {
|
||||
return;
|
||||
|
||||
if (this->current_request_ < 2) {
|
||||
auto *pkt = this->codec_->get_read_device_status_request();
|
||||
auto pkt = this->codec_->get_read_device_status_request();
|
||||
if (this->current_request_ == 0)
|
||||
this->codec_->get_set_unit_request(this->fahrenheit_ ? 'f' : 'c');
|
||||
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
|
||||
|
||||
@@ -36,7 +36,7 @@ class Anova : public climate::Climate, public esphome::ble_client::BLEClientNode
|
||||
traits.set_visual_temperature_step(0.1);
|
||||
return traits;
|
||||
}
|
||||
void set_unit_of_measurement(const char *unit);
|
||||
void set_unit_of_measurement(const char *);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<AnovaCodec> codec_;
|
||||
|
||||
@@ -225,10 +225,9 @@ void APDS9960::read_gesture_data_() {
|
||||
|
||||
uint8_t fifo_level;
|
||||
APDS9960_WARNING_CHECK(this->read_byte(0xAE, &fifo_level), "Reading FIFO level failed.");
|
||||
if (fifo_level == 0) {
|
||||
if (fifo_level == 0)
|
||||
// no data to process
|
||||
return;
|
||||
}
|
||||
|
||||
APDS9960_WARNING_CHECK(fifo_level <= 32, "FIFO level has invalid value.")
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_DIRECTION, DEVICE_CLASS_MOVING
|
||||
from esphome.const import CONF_DIRECTION, CONF_DEVICE_CLASS, DEVICE_CLASS_MOVING
|
||||
from . import APDS9960, CONF_APDS9960_ID
|
||||
|
||||
DEPENDENCIES = ["apds9960"]
|
||||
@@ -13,12 +13,13 @@ DIRECTIONS = {
|
||||
"RIGHT": "set_right_direction",
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(
|
||||
device_class=DEVICE_CLASS_MOVING
|
||||
).extend(
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
|
||||
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, upper=True),
|
||||
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
|
||||
cv.Optional(
|
||||
CONF_DEVICE_CLASS, default=DEVICE_CLASS_MOVING
|
||||
): binary_sensor.device_class,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ service APIConnection {
|
||||
rpc number_command (NumberCommandRequest) returns (void) {}
|
||||
rpc select_command (SelectCommandRequest) returns (void) {}
|
||||
rpc button_command (ButtonCommandRequest) returns (void) {}
|
||||
rpc lock_command (LockCommandRequest) returns (void) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,9 +95,6 @@ message HelloResponse {
|
||||
// and only exists for debugging/logging purposes.
|
||||
// For example "ESPHome v1.10.0 on ESP8266"
|
||||
string server_info = 3;
|
||||
|
||||
// The name of the server (App.get_name())
|
||||
string name = 4;
|
||||
}
|
||||
|
||||
// Message sent at the beginning of each connection to authenticate the client
|
||||
@@ -529,7 +525,6 @@ message ListEntitiesSwitchResponse {
|
||||
bool assumed_state = 6;
|
||||
bool disabled_by_default = 7;
|
||||
EntityCategory entity_category = 8;
|
||||
string device_class = 9;
|
||||
}
|
||||
message SwitchStateResponse {
|
||||
option (id) = 26;
|
||||
@@ -958,63 +953,6 @@ message SelectCommandRequest {
|
||||
string state = 2;
|
||||
}
|
||||
|
||||
|
||||
// ==================== LOCK ====================
|
||||
enum LockState {
|
||||
LOCK_STATE_NONE = 0;
|
||||
LOCK_STATE_LOCKED = 1;
|
||||
LOCK_STATE_UNLOCKED = 2;
|
||||
LOCK_STATE_JAMMED = 3;
|
||||
LOCK_STATE_LOCKING = 4;
|
||||
LOCK_STATE_UNLOCKING = 5;
|
||||
}
|
||||
enum LockCommand {
|
||||
LOCK_UNLOCK = 0;
|
||||
LOCK_LOCK = 1;
|
||||
LOCK_OPEN = 2;
|
||||
}
|
||||
message ListEntitiesLockResponse {
|
||||
option (id) = 58;
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_LOCK";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
string name = 3;
|
||||
string unique_id = 4;
|
||||
|
||||
string icon = 5;
|
||||
bool disabled_by_default = 6;
|
||||
EntityCategory entity_category = 7;
|
||||
bool assumed_state = 8;
|
||||
|
||||
bool supports_open = 9;
|
||||
bool requires_code = 10;
|
||||
|
||||
# Not yet implemented:
|
||||
string code_format = 11;
|
||||
}
|
||||
message LockStateResponse {
|
||||
option (id) = 59;
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_LOCK";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
LockState state = 2;
|
||||
}
|
||||
message LockCommandRequest {
|
||||
option (id) = 60;
|
||||
option (source) = SOURCE_CLIENT;
|
||||
option (ifdef) = "USE_LOCK";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
LockCommand command = 2;
|
||||
|
||||
# Not yet implemented:
|
||||
bool has_code = 3;
|
||||
string code = 4;
|
||||
}
|
||||
|
||||
// ==================== BUTTON ====================
|
||||
message ListEntitiesButtonResponse {
|
||||
option (id) = 61;
|
||||
@@ -1039,4 +977,3 @@ message ButtonCommandRequest {
|
||||
|
||||
fixed32 key = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
||||
// Shut-up about usage of deprecated speed_level_to_enum/speed_enum_to_level functions for a bit.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
bool APIConnection::send_fan_state(fan::Fan *fan) {
|
||||
bool APIConnection::send_fan_state(fan::FanState *fan) {
|
||||
if (!this->state_subscription_)
|
||||
return false;
|
||||
|
||||
@@ -273,7 +273,7 @@ bool APIConnection::send_fan_state(fan::Fan *fan) {
|
||||
resp.direction = static_cast<enums::FanDirection>(fan->direction);
|
||||
return this->send_fan_state_response(resp);
|
||||
}
|
||||
bool APIConnection::send_fan_info(fan::Fan *fan) {
|
||||
bool APIConnection::send_fan_info(fan::FanState *fan) {
|
||||
auto traits = fan->get_traits();
|
||||
ListEntitiesFanResponse msg;
|
||||
msg.key = fan->get_object_id_hash();
|
||||
@@ -290,7 +290,7 @@ bool APIConnection::send_fan_info(fan::Fan *fan) {
|
||||
return this->send_list_entities_fan_response(msg);
|
||||
}
|
||||
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
||||
fan::Fan *fan = App.get_fan_by_key(msg.key);
|
||||
fan::FanState *fan = App.get_fan_by_key(msg.key);
|
||||
if (fan == nullptr)
|
||||
return;
|
||||
|
||||
@@ -462,7 +462,6 @@ bool APIConnection::send_switch_info(switch_::Switch *a_switch) {
|
||||
msg.assumed_state = a_switch->assumed_state();
|
||||
msg.disabled_by_default = a_switch->is_disabled_by_default();
|
||||
msg.entity_category = static_cast<enums::EntityCategory>(a_switch->get_entity_category());
|
||||
msg.device_class = a_switch->get_device_class();
|
||||
return this->send_list_entities_switch_response(msg);
|
||||
}
|
||||
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
||||
@@ -470,11 +469,10 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
||||
if (a_switch == nullptr)
|
||||
return;
|
||||
|
||||
if (msg.state) {
|
||||
if (msg.state)
|
||||
a_switch->turn_on();
|
||||
} else {
|
||||
else
|
||||
a_switch->turn_off();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -701,49 +699,6 @@ void APIConnection::button_command(const ButtonCommandRequest &msg) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LOCK
|
||||
bool APIConnection::send_lock_state(lock::Lock *a_lock, lock::LockState state) {
|
||||
if (!this->state_subscription_)
|
||||
return false;
|
||||
|
||||
LockStateResponse resp{};
|
||||
resp.key = a_lock->get_object_id_hash();
|
||||
resp.state = static_cast<enums::LockState>(state);
|
||||
return this->send_lock_state_response(resp);
|
||||
}
|
||||
bool APIConnection::send_lock_info(lock::Lock *a_lock) {
|
||||
ListEntitiesLockResponse msg;
|
||||
msg.key = a_lock->get_object_id_hash();
|
||||
msg.object_id = a_lock->get_object_id();
|
||||
msg.name = a_lock->get_name();
|
||||
msg.unique_id = get_default_unique_id("lock", a_lock);
|
||||
msg.icon = a_lock->get_icon();
|
||||
msg.assumed_state = a_lock->traits.get_assumed_state();
|
||||
msg.disabled_by_default = a_lock->is_disabled_by_default();
|
||||
msg.entity_category = static_cast<enums::EntityCategory>(a_lock->get_entity_category());
|
||||
msg.supports_open = a_lock->traits.get_supports_open();
|
||||
msg.requires_code = a_lock->traits.get_requires_code();
|
||||
return this->send_list_entities_lock_response(msg);
|
||||
}
|
||||
void APIConnection::lock_command(const LockCommandRequest &msg) {
|
||||
lock::Lock *a_lock = App.get_lock_by_key(msg.key);
|
||||
if (a_lock == nullptr)
|
||||
return;
|
||||
|
||||
switch (msg.command) {
|
||||
case enums::LOCK_UNLOCK:
|
||||
a_lock->unlock();
|
||||
break;
|
||||
case enums::LOCK_LOCK:
|
||||
a_lock->lock();
|
||||
break;
|
||||
case enums::LOCK_OPEN:
|
||||
a_lock->open();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP32_CAMERA
|
||||
void APIConnection::send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image) {
|
||||
if (!this->state_subscription_)
|
||||
@@ -811,8 +766,6 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) {
|
||||
resp.api_version_major = 1;
|
||||
resp.api_version_minor = 6;
|
||||
resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
|
||||
resp.name = App.get_name();
|
||||
|
||||
this->connection_state_ = ConnectionState::CONNECTED;
|
||||
return resp;
|
||||
}
|
||||
@@ -850,16 +803,15 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
||||
resp.project_version = ESPHOME_PROJECT_VERSION;
|
||||
#endif
|
||||
#ifdef USE_WEBSERVER
|
||||
resp.webserver_port = USE_WEBSERVER_PORT;
|
||||
resp.webserver_port = WEBSERVER_PORT;
|
||||
#endif
|
||||
return resp;
|
||||
}
|
||||
void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) {
|
||||
for (auto &it : this->parent_->get_state_subs()) {
|
||||
for (auto &it : this->parent_->get_state_subs())
|
||||
if (it.entity_id == msg.entity_id && it.attribute.value() == msg.attribute) {
|
||||
it.callback(msg.state);
|
||||
}
|
||||
}
|
||||
}
|
||||
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
||||
bool found = false;
|
||||
|
||||
@@ -32,8 +32,8 @@ class APIConnection : public APIServerConnection {
|
||||
void cover_command(const CoverCommandRequest &msg) override;
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
bool send_fan_state(fan::Fan *fan);
|
||||
bool send_fan_info(fan::Fan *fan);
|
||||
bool send_fan_state(fan::FanState *fan);
|
||||
bool send_fan_info(fan::FanState *fan);
|
||||
void fan_command(const FanCommandRequest &msg) override;
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
@@ -77,11 +77,6 @@ class APIConnection : public APIServerConnection {
|
||||
#ifdef USE_BUTTON
|
||||
bool send_button_info(button::Button *button);
|
||||
void button_command(const ButtonCommandRequest &msg) override;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
|
||||
bool send_lock_info(lock::Lock *a_lock);
|
||||
void lock_command(const LockCommandRequest &msg) override;
|
||||
#endif
|
||||
bool send_log_message(int level, const char *tag, const char *line);
|
||||
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "proto.h"
|
||||
#include <cstring>
|
||||
|
||||
@@ -303,16 +302,9 @@ APIError APINoiseFrameHelper::state_action_() {
|
||||
}
|
||||
if (state_ == State::SERVER_HELLO) {
|
||||
// send server hello
|
||||
std::vector<uint8_t> msg;
|
||||
// chosen proto
|
||||
msg.push_back(0x01);
|
||||
|
||||
// node name, terminated by null byte
|
||||
const std::string &name = App.get_name();
|
||||
const uint8_t *name_ptr = reinterpret_cast<const uint8_t *>(name.c_str());
|
||||
msg.insert(msg.end(), name_ptr, name_ptr + name.size() + 1);
|
||||
|
||||
aerr = write_frame_(msg.data(), msg.size());
|
||||
uint8_t msg[1];
|
||||
msg[0] = 0x01; // chosen proto
|
||||
aerr = write_frame_(msg, 1);
|
||||
if (aerr != APIError::OK)
|
||||
return aerr;
|
||||
|
||||
|
||||
@@ -278,36 +278,6 @@ template<> const char *proto_enum_to_string<enums::NumberMode>(enums::NumberMode
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
template<> const char *proto_enum_to_string<enums::LockState>(enums::LockState value) {
|
||||
switch (value) {
|
||||
case enums::LOCK_STATE_NONE:
|
||||
return "LOCK_STATE_NONE";
|
||||
case enums::LOCK_STATE_LOCKED:
|
||||
return "LOCK_STATE_LOCKED";
|
||||
case enums::LOCK_STATE_UNLOCKED:
|
||||
return "LOCK_STATE_UNLOCKED";
|
||||
case enums::LOCK_STATE_JAMMED:
|
||||
return "LOCK_STATE_JAMMED";
|
||||
case enums::LOCK_STATE_LOCKING:
|
||||
return "LOCK_STATE_LOCKING";
|
||||
case enums::LOCK_STATE_UNLOCKING:
|
||||
return "LOCK_STATE_UNLOCKING";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
template<> const char *proto_enum_to_string<enums::LockCommand>(enums::LockCommand value) {
|
||||
switch (value) {
|
||||
case enums::LOCK_UNLOCK:
|
||||
return "LOCK_UNLOCK";
|
||||
case enums::LOCK_LOCK:
|
||||
return "LOCK_LOCK";
|
||||
case enums::LOCK_OPEN:
|
||||
return "LOCK_OPEN";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||
switch (field_id) {
|
||||
case 1: {
|
||||
@@ -349,10 +319,6 @@ bool HelloResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value)
|
||||
this->server_info = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 4: {
|
||||
this->name = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -361,7 +327,6 @@ void HelloResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_uint32(1, this->api_version_major);
|
||||
buffer.encode_uint32(2, this->api_version_minor);
|
||||
buffer.encode_string(3, this->server_info);
|
||||
buffer.encode_string(4, this->name);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void HelloResponse::dump_to(std::string &out) const {
|
||||
@@ -380,10 +345,6 @@ void HelloResponse::dump_to(std::string &out) const {
|
||||
out.append(" server_info: ");
|
||||
out.append("'").append(this->server_info).append("'");
|
||||
out.append("\n");
|
||||
|
||||
out.append(" name: ");
|
||||
out.append("'").append(this->name).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
@@ -2177,10 +2138,6 @@ bool ListEntitiesSwitchResponse::decode_length(uint32_t field_id, ProtoLengthDel
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 9: {
|
||||
this->device_class = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -2204,7 +2161,6 @@ void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_bool(6, this->assumed_state);
|
||||
buffer.encode_bool(7, this->disabled_by_default);
|
||||
buffer.encode_enum<enums::EntityCategory>(8, this->entity_category);
|
||||
buffer.encode_string(9, this->device_class);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesSwitchResponse::dump_to(std::string &out) const {
|
||||
@@ -2242,10 +2198,6 @@ void ListEntitiesSwitchResponse::dump_to(std::string &out) const {
|
||||
out.append(" entity_category: ");
|
||||
out.append(proto_enum_to_string<enums::EntityCategory>(this->entity_category));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" device_class: ");
|
||||
out.append("'").append(this->device_class).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
@@ -4225,234 +4177,6 @@ void SelectCommandRequest::dump_to(std::string &out) const {
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
bool ListEntitiesLockResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 6: {
|
||||
this->disabled_by_default = value.as_bool();
|
||||
return true;
|
||||
}
|
||||
case 7: {
|
||||
this->entity_category = value.as_enum<enums::EntityCategory>();
|
||||
return true;
|
||||
}
|
||||
case 8: {
|
||||
this->assumed_state = value.as_bool();
|
||||
return true;
|
||||
}
|
||||
case 9: {
|
||||
this->supports_open = value.as_bool();
|
||||
return true;
|
||||
}
|
||||
case 10: {
|
||||
this->requires_code = value.as_bool();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ListEntitiesLockResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||
switch (field_id) {
|
||||
case 1: {
|
||||
this->object_id = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 3: {
|
||||
this->name = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 4: {
|
||||
this->unique_id = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 5: {
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 11: {
|
||||
this->code_format = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ListEntitiesLockResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
switch (field_id) {
|
||||
case 2: {
|
||||
this->key = value.as_fixed32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void ListEntitiesLockResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
buffer.encode_string(4, this->unique_id);
|
||||
buffer.encode_string(5, this->icon);
|
||||
buffer.encode_bool(6, this->disabled_by_default);
|
||||
buffer.encode_enum<enums::EntityCategory>(7, this->entity_category);
|
||||
buffer.encode_bool(8, this->assumed_state);
|
||||
buffer.encode_bool(9, this->supports_open);
|
||||
buffer.encode_bool(10, this->requires_code);
|
||||
buffer.encode_string(11, this->code_format);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesLockResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
out.append("ListEntitiesLockResponse {\n");
|
||||
out.append(" object_id: ");
|
||||
out.append("'").append(this->object_id).append("'");
|
||||
out.append("\n");
|
||||
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" name: ");
|
||||
out.append("'").append(this->name).append("'");
|
||||
out.append("\n");
|
||||
|
||||
out.append(" unique_id: ");
|
||||
out.append("'").append(this->unique_id).append("'");
|
||||
out.append("\n");
|
||||
|
||||
out.append(" icon: ");
|
||||
out.append("'").append(this->icon).append("'");
|
||||
out.append("\n");
|
||||
|
||||
out.append(" disabled_by_default: ");
|
||||
out.append(YESNO(this->disabled_by_default));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" entity_category: ");
|
||||
out.append(proto_enum_to_string<enums::EntityCategory>(this->entity_category));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" assumed_state: ");
|
||||
out.append(YESNO(this->assumed_state));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" supports_open: ");
|
||||
out.append(YESNO(this->supports_open));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" requires_code: ");
|
||||
out.append(YESNO(this->requires_code));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" code_format: ");
|
||||
out.append("'").append(this->code_format).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
bool LockStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 2: {
|
||||
this->state = value.as_enum<enums::LockState>();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool LockStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
switch (field_id) {
|
||||
case 1: {
|
||||
this->key = value.as_fixed32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void LockStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_enum<enums::LockState>(2, this->state);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
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);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" state: ");
|
||||
out.append(proto_enum_to_string<enums::LockState>(this->state));
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
bool LockCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 2: {
|
||||
this->command = value.as_enum<enums::LockCommand>();
|
||||
return true;
|
||||
}
|
||||
case 3: {
|
||||
this->has_code = value.as_bool();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool LockCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||
switch (field_id) {
|
||||
case 4: {
|
||||
this->code = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool LockCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
switch (field_id) {
|
||||
case 1: {
|
||||
this->key = value.as_fixed32();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void LockCommandRequest::encode(ProtoWriteBuffer buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_enum<enums::LockCommand>(2, this->command);
|
||||
buffer.encode_bool(3, this->has_code);
|
||||
buffer.encode_string(4, this->code);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
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);
|
||||
out.append(buffer);
|
||||
out.append("\n");
|
||||
|
||||
out.append(" command: ");
|
||||
out.append(proto_enum_to_string<enums::LockCommand>(this->command));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" has_code: ");
|
||||
out.append(YESNO(this->has_code));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" code: ");
|
||||
out.append("'").append(this->code).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
bool ListEntitiesButtonResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
case 6: {
|
||||
@@ -4515,7 +4239,7 @@ void ListEntitiesButtonResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesButtonResponse::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
char buffer[64];
|
||||
out.append("ListEntitiesButtonResponse {\n");
|
||||
out.append(" object_id: ");
|
||||
out.append("'").append(this->object_id).append("'");
|
||||
@@ -4565,7 +4289,7 @@ bool ButtonCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
void ButtonCommandRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->key); }
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ButtonCommandRequest::dump_to(std::string &out) const {
|
||||
__attribute__((unused)) char buffer[64];
|
||||
char buffer[64];
|
||||
out.append("ButtonCommandRequest {\n");
|
||||
out.append(" key: ");
|
||||
sprintf(buffer, "%u", this->key);
|
||||
|
||||
@@ -128,19 +128,6 @@ enum NumberMode : uint32_t {
|
||||
NUMBER_MODE_BOX = 1,
|
||||
NUMBER_MODE_SLIDER = 2,
|
||||
};
|
||||
enum LockState : uint32_t {
|
||||
LOCK_STATE_NONE = 0,
|
||||
LOCK_STATE_LOCKED = 1,
|
||||
LOCK_STATE_UNLOCKED = 2,
|
||||
LOCK_STATE_JAMMED = 3,
|
||||
LOCK_STATE_LOCKING = 4,
|
||||
LOCK_STATE_UNLOCKING = 5,
|
||||
};
|
||||
enum LockCommand : uint32_t {
|
||||
LOCK_UNLOCK = 0,
|
||||
LOCK_LOCK = 1,
|
||||
LOCK_OPEN = 2,
|
||||
};
|
||||
|
||||
} // namespace enums
|
||||
|
||||
@@ -160,7 +147,6 @@ class HelloResponse : public ProtoMessage {
|
||||
uint32_t api_version_major{0};
|
||||
uint32_t api_version_minor{0};
|
||||
std::string server_info{};
|
||||
std::string name{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
@@ -580,7 +566,6 @@ class ListEntitiesSwitchResponse : public ProtoMessage {
|
||||
bool assumed_state{false};
|
||||
bool disabled_by_default{false};
|
||||
enums::EntityCategory entity_category{};
|
||||
std::string device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
@@ -1063,58 +1048,6 @@ class SelectCommandRequest : public ProtoMessage {
|
||||
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
|
||||
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
||||
};
|
||||
class ListEntitiesLockResponse : public ProtoMessage {
|
||||
public:
|
||||
std::string object_id{};
|
||||
uint32_t key{0};
|
||||
std::string name{};
|
||||
std::string unique_id{};
|
||||
std::string icon{};
|
||||
bool disabled_by_default{false};
|
||||
enums::EntityCategory entity_category{};
|
||||
bool assumed_state{false};
|
||||
bool supports_open{false};
|
||||
bool requires_code{false};
|
||||
std::string code_format{};
|
||||
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_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
||||
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
||||
};
|
||||
class LockStateResponse : public ProtoMessage {
|
||||
public:
|
||||
uint32_t key{0};
|
||||
enums::LockState state{};
|
||||
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 LockCommandRequest : public ProtoMessage {
|
||||
public:
|
||||
uint32_t key{0};
|
||||
enums::LockCommand command{};
|
||||
bool has_code{false};
|
||||
std::string code{};
|
||||
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_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
||||
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
||||
};
|
||||
class ListEntitiesButtonResponse : public ProtoMessage {
|
||||
public:
|
||||
std::string object_id{};
|
||||
|
||||
@@ -282,24 +282,6 @@ bool APIServerConnectionBase::send_select_state_response(const SelectStateRespon
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool APIServerConnectionBase::send_list_entities_lock_response(const ListEntitiesLockResponse &msg) {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "send_list_entities_lock_response: %s", msg.dump().c_str());
|
||||
#endif
|
||||
return this->send_message_<ListEntitiesLockResponse>(msg, 58);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool APIServerConnectionBase::send_lock_state_response(const LockStateResponse &msg) {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "send_lock_state_response: %s", msg.dump().c_str());
|
||||
#endif
|
||||
return this->send_message_<LockStateResponse>(msg, 59);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
#endif
|
||||
#ifdef USE_BUTTON
|
||||
bool APIServerConnectionBase::send_list_entities_button_response(const ListEntitiesButtonResponse &msg) {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
@@ -541,17 +523,6 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
ESP_LOGVV(TAG, "on_select_command_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
this->on_select_command_request(msg);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 60: {
|
||||
#ifdef USE_LOCK
|
||||
LockCommandRequest msg;
|
||||
msg.decode(msg_data, msg_size);
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
ESP_LOGVV(TAG, "on_lock_command_request: %s", msg.dump().c_str());
|
||||
#endif
|
||||
this->on_lock_command_request(msg);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -800,19 +771,6 @@ void APIServerConnection::on_button_command_request(const ButtonCommandRequest &
|
||||
this->button_command(msg);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
void APIServerConnection::on_lock_command_request(const LockCommandRequest &msg) {
|
||||
if (!this->is_connection_setup()) {
|
||||
this->on_no_setup_connection();
|
||||
return;
|
||||
}
|
||||
if (!this->is_authenticated()) {
|
||||
this->on_unauthenticated_access();
|
||||
return;
|
||||
}
|
||||
this->lock_command(msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace api
|
||||
} // namespace esphome
|
||||
|
||||
@@ -130,15 +130,6 @@ class APIServerConnectionBase : public ProtoService {
|
||||
#ifdef USE_SELECT
|
||||
virtual void on_select_command_request(const SelectCommandRequest &value){};
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool send_list_entities_lock_response(const ListEntitiesLockResponse &msg);
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool send_lock_state_response(const LockStateResponse &msg);
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
virtual void on_lock_command_request(const LockCommandRequest &value){};
|
||||
#endif
|
||||
#ifdef USE_BUTTON
|
||||
bool send_list_entities_button_response(const ListEntitiesButtonResponse &msg);
|
||||
#endif
|
||||
@@ -189,9 +180,6 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||
#endif
|
||||
#ifdef USE_BUTTON
|
||||
virtual void button_command(const ButtonCommandRequest &msg) = 0;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
virtual void lock_command(const LockCommandRequest &msg) = 0;
|
||||
#endif
|
||||
protected:
|
||||
void on_hello_request(const HelloRequest &msg) override;
|
||||
@@ -233,9 +221,6 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||
#ifdef USE_BUTTON
|
||||
void on_button_command_request(const ButtonCommandRequest &msg) override;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
void on_lock_command_request(const LockCommandRequest &msg) override;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -24,7 +24,7 @@ static const char *const TAG = "api";
|
||||
void APIServer::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Home Assistant API server...");
|
||||
this->setup_controller();
|
||||
socket_ = socket::socket_ip(SOCK_STREAM, 0);
|
||||
socket_ = socket::socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket_ == nullptr) {
|
||||
ESP_LOGW(TAG, "Could not create socket.");
|
||||
this->mark_failed();
|
||||
@@ -43,16 +43,13 @@ void APIServer::setup() {
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_storage server;
|
||||
struct sockaddr_in server;
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = ESPHOME_INADDR_ANY;
|
||||
server.sin_port = htons(this->port_);
|
||||
|
||||
socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), htons(this->port_));
|
||||
if (sl == 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno);
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
err = socket_->bind((struct sockaddr *) &server, sl);
|
||||
err = socket_->bind((struct sockaddr *) &server, sizeof(server));
|
||||
if (err != 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
|
||||
this->mark_failed();
|
||||
@@ -83,10 +80,9 @@ void APIServer::setup() {
|
||||
if (esp32_camera::global_esp32_camera != nullptr && !esp32_camera::global_esp32_camera->is_internal()) {
|
||||
esp32_camera::global_esp32_camera->add_image_callback(
|
||||
[this](const std::shared_ptr<esp32_camera::CameraImage> &image) {
|
||||
for (auto &c : this->clients_) {
|
||||
for (auto &c : this->clients_)
|
||||
if (!c->remove_)
|
||||
c->send_camera_state(image);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
@@ -192,7 +188,7 @@ void APIServer::on_cover_update(cover::Cover *obj) {
|
||||
#endif
|
||||
|
||||
#ifdef USE_FAN
|
||||
void APIServer::on_fan_update(fan::Fan *obj) {
|
||||
void APIServer::on_fan_update(fan::FanState *obj) {
|
||||
if (obj->is_internal())
|
||||
return;
|
||||
for (auto &c : this->clients_)
|
||||
@@ -263,15 +259,6 @@ void APIServer::on_select_update(select::Select *obj, const std::string &state)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LOCK
|
||||
void APIServer::on_lock_update(lock::Lock *obj) {
|
||||
if (obj->is_internal())
|
||||
return;
|
||||
for (auto &c : this->clients_)
|
||||
c->send_lock_state(obj, obj->state);
|
||||
}
|
||||
#endif
|
||||
|
||||
float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
||||
void APIServer::set_port(uint16_t port) { this->port_ = port; }
|
||||
APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
@@ -44,7 +44,7 @@ class APIServer : public Component, public Controller {
|
||||
void on_cover_update(cover::Cover *obj) override;
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
void on_fan_update(fan::Fan *obj) override;
|
||||
void on_fan_update(fan::FanState *obj) override;
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
void on_light_update(light::LightState *obj) override;
|
||||
@@ -66,9 +66,6 @@ class APIServer : public Component, public Controller {
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
void on_select_update(select::Select *obj, const std::string &state) override;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
void on_lock_update(lock::Lock *obj) override;
|
||||
#endif
|
||||
void send_homeassistant_service_call(const HomeassistantServiceResponse &call);
|
||||
void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
|
||||
|
||||
@@ -21,6 +21,7 @@ async def async_run_logs(config, address):
|
||||
if CONF_ENCRYPTION in conf:
|
||||
noise_psk = conf[CONF_ENCRYPTION][CONF_KEY]
|
||||
_LOGGER.info("Starting log output from %s using esphome API", address)
|
||||
zc = zeroconf.Zeroconf()
|
||||
cli = APIClient(
|
||||
address,
|
||||
port,
|
||||
|
||||
@@ -16,7 +16,7 @@ bool ListEntitiesIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_
|
||||
bool ListEntitiesIterator::on_cover(cover::Cover *cover) { return this->client_->send_cover_info(cover); }
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
bool ListEntitiesIterator::on_fan(fan::Fan *fan) { return this->client_->send_fan_info(fan); }
|
||||
bool ListEntitiesIterator::on_fan(fan::FanState *fan) { return this->client_->send_fan_info(fan); }
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
bool ListEntitiesIterator::on_light(light::LightState *light) { return this->client_->send_light_info(light); }
|
||||
@@ -35,9 +35,6 @@ bool ListEntitiesIterator::on_text_sensor(text_sensor::TextSensor *text_sensor)
|
||||
return this->client_->send_text_sensor_info(text_sensor);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool ListEntitiesIterator::on_lock(lock::Lock *a_lock) { return this->client_->send_lock_info(a_lock); }
|
||||
#endif
|
||||
|
||||
bool ListEntitiesIterator::on_end() { return this->client_->send_list_info_done(); }
|
||||
ListEntitiesIterator::ListEntitiesIterator(APIServer *server, APIConnection *client)
|
||||
|
||||
@@ -19,7 +19,7 @@ class ListEntitiesIterator : public ComponentIterator {
|
||||
bool on_cover(cover::Cover *cover) override;
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
bool on_fan(fan::Fan *fan) override;
|
||||
bool on_fan(fan::FanState *fan) override;
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
bool on_light(light::LightState *light) override;
|
||||
@@ -48,9 +48,6 @@ class ListEntitiesIterator : public ComponentIterator {
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
bool on_select(select::Select *select) override;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool on_lock(lock::Lock *a_lock) override;
|
||||
#endif
|
||||
bool on_end() override;
|
||||
|
||||
|
||||
@@ -55,19 +55,17 @@ class ProtoVarInt {
|
||||
}
|
||||
int32_t as_sint32() const {
|
||||
// with ZigZag encoding
|
||||
if (this->value_ & 1) {
|
||||
if (this->value_ & 1)
|
||||
return static_cast<int32_t>(~(this->value_ >> 1));
|
||||
} else {
|
||||
else
|
||||
return static_cast<int32_t>(this->value_ >> 1);
|
||||
}
|
||||
}
|
||||
int64_t as_sint64() const {
|
||||
// with ZigZag encoding
|
||||
if (this->value_ & 1) {
|
||||
if (this->value_ & 1)
|
||||
return static_cast<int64_t>(~(this->value_ >> 1));
|
||||
} else {
|
||||
else
|
||||
return static_cast<int64_t>(this->value_ >> 1);
|
||||
}
|
||||
}
|
||||
void encode(std::vector<uint8_t> &out) {
|
||||
uint32_t val = this->value_;
|
||||
@@ -222,11 +220,10 @@ class ProtoWriteBuffer {
|
||||
}
|
||||
void encode_sint32(uint32_t field_id, int32_t value, bool force = false) {
|
||||
uint32_t uvalue;
|
||||
if (value < 0) {
|
||||
if (value < 0)
|
||||
uvalue = ~(value << 1);
|
||||
} else {
|
||||
else
|
||||
uvalue = value << 1;
|
||||
}
|
||||
this->encode_uint32(field_id, uvalue, force);
|
||||
}
|
||||
template<class C> void encode_message(uint32_t field_id, const C &value, bool force = false) {
|
||||
|
||||
@@ -14,7 +14,7 @@ bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_
|
||||
bool InitialStateIterator::on_cover(cover::Cover *cover) { return this->client_->send_cover_state(cover); }
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
bool InitialStateIterator::on_fan(fan::Fan *fan) { return this->client_->send_fan_state(fan); }
|
||||
bool InitialStateIterator::on_fan(fan::FanState *fan) { return this->client_->send_fan_state(fan); }
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
bool InitialStateIterator::on_light(light::LightState *light) { return this->client_->send_light_state(light); }
|
||||
@@ -47,9 +47,6 @@ bool InitialStateIterator::on_select(select::Select *select) {
|
||||
return this->client_->send_select_state(select, select->state);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool InitialStateIterator::on_lock(lock::Lock *a_lock) { return this->client_->send_lock_state(a_lock, a_lock->state); }
|
||||
#endif
|
||||
InitialStateIterator::InitialStateIterator(APIServer *server, APIConnection *client)
|
||||
: ComponentIterator(server), client_(client) {}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class InitialStateIterator : public ComponentIterator {
|
||||
bool on_cover(cover::Cover *cover) override;
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
bool on_fan(fan::Fan *fan) override;
|
||||
bool on_fan(fan::FanState *fan) override;
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
bool on_light(light::LightState *light) override;
|
||||
@@ -45,9 +45,6 @@ class InitialStateIterator : public ComponentIterator {
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
bool on_select(select::Select *select) override;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
bool on_lock(lock::Lock *a_lock) override;
|
||||
#endif
|
||||
protected:
|
||||
APIConnection *client_;
|
||||
|
||||
@@ -52,7 +52,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
|
||||
|
||||
protected:
|
||||
virtual void execute(Ts... x) = 0;
|
||||
template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...> type) {
|
||||
template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...>) {
|
||||
this->execute((get_execute_arg_value<Ts>(args[S]))...);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,21 +212,6 @@ void ComponentIterator::advance() {
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
case IteratorState::LOCK:
|
||||
if (this->at_ >= App.get_locks().size()) {
|
||||
advance_platform = true;
|
||||
} else {
|
||||
auto *a_lock = App.get_locks()[this->at_];
|
||||
if (a_lock->is_internal()) {
|
||||
success = true;
|
||||
break;
|
||||
} else {
|
||||
success = this->on_lock(a_lock);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case IteratorState::MAX:
|
||||
if (this->on_end()) {
|
||||
|
||||
@@ -27,7 +27,7 @@ class ComponentIterator {
|
||||
virtual bool on_cover(cover::Cover *cover) = 0;
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
virtual bool on_fan(fan::Fan *fan) = 0;
|
||||
virtual bool on_fan(fan::FanState *fan) = 0;
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
virtual bool on_light(light::LightState *light) = 0;
|
||||
@@ -56,9 +56,6 @@ class ComponentIterator {
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
virtual bool on_select(select::Select *select) = 0;
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
virtual bool on_lock(lock::Lock *a_lock) = 0;
|
||||
#endif
|
||||
virtual bool on_end();
|
||||
|
||||
@@ -102,9 +99,6 @@ class ComponentIterator {
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
SELECT,
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
LOCK,
|
||||
#endif
|
||||
MAX,
|
||||
} state_{IteratorState::NONE};
|
||||
|
||||
@@ -58,11 +58,10 @@ void AS3935Component::loop() {
|
||||
|
||||
void AS3935Component::write_indoor(bool indoor) {
|
||||
ESP_LOGV(TAG, "Setting indoor to %d", indoor);
|
||||
if (indoor) {
|
||||
if (indoor)
|
||||
this->write_register(AFE_GAIN, GAIN_MASK, INDOOR, 1);
|
||||
} else {
|
||||
else
|
||||
this->write_register(AFE_GAIN, GAIN_MASK, OUTDOOR, 1);
|
||||
}
|
||||
}
|
||||
// REG0x01, bits[3:0], manufacturer default: 0010 (2).
|
||||
// This setting determines the threshold for events that trigger the
|
||||
|
||||
@@ -5,7 +5,7 @@ from . import AS3935, CONF_AS3935_ID
|
||||
|
||||
DEPENDENCIES = ["as3935"]
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema().extend(
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_AS3935_ID): cv.use_id(AS3935),
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ from esphome.components import sensor
|
||||
from esphome.const import (
|
||||
CONF_DISTANCE,
|
||||
CONF_LIGHTNING_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_KILOMETER,
|
||||
ICON_SIGNAL_DISTANCE_VARIANT,
|
||||
ICON_FLASH,
|
||||
@@ -19,10 +20,12 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
unit_of_measurement=UNIT_KILOMETER,
|
||||
icon=ICON_SIGNAL_DISTANCE_VARIANT,
|
||||
accuracy_decimals=1,
|
||||
state_class=STATE_CLASS_NONE,
|
||||
),
|
||||
cv.Optional(CONF_LIGHTNING_ENERGY): sensor.sensor_schema(
|
||||
icon=ICON_FLASH,
|
||||
accuracy_decimals=1,
|
||||
state_class=STATE_CLASS_NONE,
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
@@ -97,7 +97,7 @@ void BalluClimate::transmit_state() {
|
||||
|
||||
// Send code
|
||||
auto transmit = this->transmitter_->transmit();
|
||||
auto *data = transmit.get_data();
|
||||
auto data = transmit.get_data();
|
||||
|
||||
data->set_carrier_frequency(38000);
|
||||
|
||||
@@ -130,10 +130,10 @@ bool BalluClimate::on_receive(remote_base::RemoteReceiveData data) {
|
||||
for (int i = 0; i < BALLU_STATE_LENGTH; i++) {
|
||||
// Read bit
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (data.expect_item(BALLU_BIT_MARK, BALLU_ONE_SPACE)) {
|
||||
if (data.expect_item(BALLU_BIT_MARK, BALLU_ONE_SPACE))
|
||||
remote_state[i] |= 1 << j;
|
||||
|
||||
} else if (!data.expect_item(BALLU_BIT_MARK, BALLU_ZERO_SPACE)) {
|
||||
else if (!data.expect_item(BALLU_BIT_MARK, BALLU_ZERO_SPACE)) {
|
||||
ESP_LOGV(TAG, "Byte %d bit %d fail", i, j);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -21,13 +21,12 @@ void BangBangClimate::setup() {
|
||||
restore->to_call(this).perform();
|
||||
} else {
|
||||
// restore from defaults, change_away handles those for us
|
||||
if (supports_cool_ && supports_heat_) {
|
||||
if (supports_cool_ && supports_heat_)
|
||||
this->mode = climate::CLIMATE_MODE_HEAT_COOL;
|
||||
} else if (supports_cool_) {
|
||||
else if (supports_cool_)
|
||||
this->mode = climate::CLIMATE_MODE_COOL;
|
||||
} else if (supports_heat_) {
|
||||
else if (supports_heat_)
|
||||
this->mode = climate::CLIMATE_MODE_HEAT;
|
||||
}
|
||||
this->change_away_(false);
|
||||
}
|
||||
}
|
||||
@@ -57,12 +56,11 @@ climate::ClimateTraits BangBangClimate::traits() {
|
||||
if (supports_cool_ && supports_heat_)
|
||||
traits.add_supported_mode(climate::CLIMATE_MODE_HEAT_COOL);
|
||||
traits.set_supports_two_point_target_temperature(true);
|
||||
if (supports_away_) {
|
||||
if (supports_away_)
|
||||
traits.set_supported_presets({
|
||||
climate::CLIMATE_PRESET_HOME,
|
||||
climate::CLIMATE_PRESET_AWAY,
|
||||
});
|
||||
}
|
||||
traits.set_supports_action(true);
|
||||
return traits;
|
||||
}
|
||||
@@ -84,19 +82,17 @@ void BangBangClimate::compute_state_() {
|
||||
if (too_cold) {
|
||||
// too cold -> enable heating if possible and enabled, else idle
|
||||
if (this->supports_heat_ &&
|
||||
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_HEAT)) {
|
||||
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_HEAT))
|
||||
target_action = climate::CLIMATE_ACTION_HEATING;
|
||||
} else {
|
||||
else
|
||||
target_action = climate::CLIMATE_ACTION_IDLE;
|
||||
}
|
||||
} else if (too_hot) {
|
||||
// too hot -> enable cooling if possible and enabled, else idle
|
||||
if (this->supports_cool_ &&
|
||||
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_COOL)) {
|
||||
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_COOL))
|
||||
target_action = climate::CLIMATE_ACTION_COOLING;
|
||||
} else {
|
||||
else
|
||||
target_action = climate::CLIMATE_ACTION_IDLE;
|
||||
}
|
||||
} else {
|
||||
// neither too hot nor too cold -> in range
|
||||
if (this->supports_cool_ && this->supports_heat_ && this->mode == climate::CLIMATE_MODE_HEAT_COOL) {
|
||||
@@ -111,10 +107,9 @@ void BangBangClimate::compute_state_() {
|
||||
this->switch_to_action_(target_action);
|
||||
}
|
||||
void BangBangClimate::switch_to_action_(climate::ClimateAction action) {
|
||||
if (action == this->action) {
|
||||
if (action == this->action)
|
||||
// already in target mode
|
||||
return;
|
||||
}
|
||||
|
||||
if ((action == climate::CLIMATE_ACTION_OFF && this->action == climate::CLIMATE_ACTION_IDLE) ||
|
||||
(action == climate::CLIMATE_ACTION_IDLE && this->action == climate::CLIMATE_ACTION_OFF)) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_RESOLUTION,
|
||||
DEVICE_CLASS_ILLUMINANCE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
@@ -26,7 +27,6 @@ BH1750Sensor = bh1750_ns.class_(
|
||||
CONF_MEASUREMENT_TIME = "measurement_time"
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
BH1750Sensor,
|
||||
unit_of_measurement=UNIT_LUX,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_ILLUMINANCE,
|
||||
@@ -34,6 +34,7 @@ CONFIG_SCHEMA = (
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BH1750Sensor),
|
||||
cv.Optional(CONF_RESOLUTION, default=0.5): cv.enum(
|
||||
BH1750_RESOLUTIONS, float=True
|
||||
),
|
||||
@@ -51,8 +52,9 @@ CONFIG_SCHEMA = (
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await sensor.register_sensor(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_resolution(config[CONF_RESOLUTION]))
|
||||
|
||||
@@ -9,7 +9,7 @@ from esphome.const import (
|
||||
)
|
||||
from .. import binary_ns
|
||||
|
||||
BinaryFan = binary_ns.class_("BinaryFan", fan.Fan, cg.Component)
|
||||
BinaryFan = binary_ns.class_("BinaryFan", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = fan.FAN_SCHEMA.extend(
|
||||
{
|
||||
@@ -24,8 +24,9 @@ CONFIG_SCHEMA = fan.FAN_SCHEMA.extend(
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
|
||||
await cg.register_component(var, config)
|
||||
await fan.register_fan(var, config)
|
||||
|
||||
fan_ = await fan.create_fan_state(config)
|
||||
cg.add(var.set_fan(fan_))
|
||||
output_ = await cg.get_variable(config[CONF_OUTPUT])
|
||||
cg.add(var.set_output(output_))
|
||||
|
||||
|
||||
@@ -6,35 +6,59 @@ namespace binary {
|
||||
|
||||
static const char *const TAG = "binary.fan";
|
||||
|
||||
void BinaryFan::setup() {
|
||||
auto restore = this->restore_state_();
|
||||
if (restore.has_value()) {
|
||||
restore->apply(*this);
|
||||
this->write_state_();
|
||||
void binary::BinaryFan::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Fan '%s':", this->fan_->get_name().c_str());
|
||||
if (this->fan_->get_traits().supports_oscillation()) {
|
||||
ESP_LOGCONFIG(TAG, " Oscillation: YES");
|
||||
}
|
||||
if (this->fan_->get_traits().supports_direction()) {
|
||||
ESP_LOGCONFIG(TAG, " Direction: YES");
|
||||
}
|
||||
}
|
||||
void BinaryFan::dump_config() { LOG_FAN("", "Binary Fan", this); }
|
||||
fan::FanTraits BinaryFan::get_traits() {
|
||||
return fan::FanTraits(this->oscillating_ != nullptr, false, this->direction_ != nullptr, 0);
|
||||
void BinaryFan::setup() {
|
||||
auto traits = fan::FanTraits(this->oscillating_ != nullptr, false, this->direction_ != nullptr, 0);
|
||||
this->fan_->set_traits(traits);
|
||||
this->fan_->add_on_state_callback([this]() { this->next_update_ = true; });
|
||||
}
|
||||
void BinaryFan::control(const fan::FanCall &call) {
|
||||
if (call.get_state().has_value())
|
||||
this->state = *call.get_state();
|
||||
if (call.get_oscillating().has_value())
|
||||
this->oscillating = *call.get_oscillating();
|
||||
if (call.get_direction().has_value())
|
||||
this->direction = *call.get_direction();
|
||||
void BinaryFan::loop() {
|
||||
if (!this->next_update_) {
|
||||
return;
|
||||
}
|
||||
this->next_update_ = false;
|
||||
|
||||
this->write_state_();
|
||||
this->publish_state();
|
||||
}
|
||||
void BinaryFan::write_state_() {
|
||||
this->output_->set_state(this->state);
|
||||
if (this->oscillating_ != nullptr)
|
||||
this->oscillating_->set_state(this->oscillating);
|
||||
if (this->direction_ != nullptr)
|
||||
this->direction_->set_state(this->direction == fan::FanDirection::REVERSE);
|
||||
{
|
||||
bool enable = this->fan_->state;
|
||||
if (enable)
|
||||
this->output_->turn_on();
|
||||
else
|
||||
this->output_->turn_off();
|
||||
ESP_LOGD(TAG, "Setting binary state: %s", ONOFF(enable));
|
||||
}
|
||||
|
||||
if (this->oscillating_ != nullptr) {
|
||||
bool enable = this->fan_->oscillating;
|
||||
if (enable) {
|
||||
this->oscillating_->turn_on();
|
||||
} else {
|
||||
this->oscillating_->turn_off();
|
||||
}
|
||||
ESP_LOGD(TAG, "Setting oscillation: %s", ONOFF(enable));
|
||||
}
|
||||
|
||||
if (this->direction_ != nullptr) {
|
||||
bool enable = this->fan_->direction == fan::FAN_DIRECTION_REVERSE;
|
||||
if (enable) {
|
||||
this->direction_->turn_on();
|
||||
} else {
|
||||
this->direction_->turn_off();
|
||||
}
|
||||
ESP_LOGD(TAG, "Setting reverse direction: %s", ONOFF(enable));
|
||||
}
|
||||
}
|
||||
|
||||
// We need a higher priority than the FanState component to make sure that the traits are set
|
||||
// when that component sets itself up.
|
||||
float BinaryFan::get_setup_priority() const { return fan_->get_setup_priority() + 1.0f; }
|
||||
|
||||
} // namespace binary
|
||||
} // namespace esphome
|
||||
|
||||
@@ -2,29 +2,28 @@
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
#include "esphome/components/fan/fan.h"
|
||||
#include "esphome/components/fan/fan_state.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace binary {
|
||||
|
||||
class BinaryFan : public Component, public fan::Fan {
|
||||
class BinaryFan : public Component {
|
||||
public:
|
||||
void set_fan(fan::FanState *fan) { fan_ = fan; }
|
||||
void set_output(output::BinaryOutput *output) { output_ = output; }
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
|
||||
void set_output(output::BinaryOutput *output) { this->output_ = output; }
|
||||
float get_setup_priority() const override;
|
||||
void set_oscillating(output::BinaryOutput *oscillating) { this->oscillating_ = oscillating; }
|
||||
void set_direction(output::BinaryOutput *direction) { this->direction_ = direction; }
|
||||
|
||||
fan::FanTraits get_traits() override;
|
||||
|
||||
protected:
|
||||
void control(const fan::FanCall &call) override;
|
||||
void write_state_();
|
||||
|
||||
fan::FanState *fan_;
|
||||
output::BinaryOutput *output_;
|
||||
output::BinaryOutput *oscillating_{nullptr};
|
||||
output::BinaryOutput *direction_{nullptr};
|
||||
bool next_update_{true};
|
||||
};
|
||||
|
||||
} // namespace binary
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from esphome import automation, core
|
||||
from esphome.automation import Condition, maybe_simple_id
|
||||
@@ -8,9 +7,7 @@ from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DELAY,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_ENTITY_CATEGORY,
|
||||
CONF_FILTERS,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INVALID_COOLDOWN,
|
||||
CONF_INVERTED,
|
||||
@@ -25,6 +22,7 @@ from esphome.const import (
|
||||
CONF_STATE,
|
||||
CONF_TIMING,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
@@ -317,7 +315,7 @@ def validate_multi_click_timing(value):
|
||||
return timings
|
||||
|
||||
|
||||
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
||||
device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
||||
|
||||
|
||||
BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
@@ -326,7 +324,7 @@ BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).ex
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(
|
||||
mqtt.MQTTBinarySensorComponent
|
||||
),
|
||||
cv.Optional(CONF_DEVICE_CLASS): validate_device_class,
|
||||
cv.Optional(CONF_DEVICE_CLASS): device_class,
|
||||
cv.Optional(CONF_FILTERS): validate_filters,
|
||||
cv.Optional(CONF_ON_PRESS): automation.validate_automation(
|
||||
{
|
||||
@@ -379,39 +377,6 @@ BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).ex
|
||||
}
|
||||
)
|
||||
|
||||
_UNDEF = object()
|
||||
|
||||
|
||||
def binary_sensor_schema(
|
||||
class_: MockObjClass = _UNDEF,
|
||||
*,
|
||||
icon: str = _UNDEF,
|
||||
entity_category: str = _UNDEF,
|
||||
device_class: str = _UNDEF,
|
||||
) -> cv.Schema:
|
||||
schema = BINARY_SENSOR_SCHEMA
|
||||
if class_ is not _UNDEF:
|
||||
schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)})
|
||||
if icon is not _UNDEF:
|
||||
schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
|
||||
if entity_category is not _UNDEF:
|
||||
schema = schema.extend(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_ENTITY_CATEGORY, default=entity_category
|
||||
): cv.entity_category
|
||||
}
|
||||
)
|
||||
if device_class is not _UNDEF:
|
||||
schema = schema.extend(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_DEVICE_CLASS, default=device_class
|
||||
): validate_device_class
|
||||
}
|
||||
)
|
||||
return schema
|
||||
|
||||
|
||||
async def setup_binary_sensor_core_(var, config):
|
||||
await setup_entity(var, config)
|
||||
@@ -478,7 +443,7 @@ async def register_binary_sensor(var, config):
|
||||
|
||||
|
||||
async def new_binary_sensor(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], config[CONF_NAME])
|
||||
await register_binary_sensor(var, config)
|
||||
return var
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ void BinarySensor::send_state_internal(bool state, bool is_initial) {
|
||||
}
|
||||
}
|
||||
std::string BinarySensor::device_class() { return ""; }
|
||||
BinarySensor::BinarySensor() : state(false) {}
|
||||
BinarySensor::BinarySensor(const std::string &name) : EntityBase(name), state(false) {}
|
||||
BinarySensor::BinarySensor() : BinarySensor("") {}
|
||||
void BinarySensor::set_device_class(const std::string &device_class) { this->device_class_ = device_class; }
|
||||
std::string BinarySensor::get_device_class() {
|
||||
if (this->device_class_.has_value())
|
||||
|
||||
@@ -26,6 +26,11 @@ namespace binary_sensor {
|
||||
class BinarySensor : public EntityBase {
|
||||
public:
|
||||
explicit BinarySensor();
|
||||
/** Construct a binary sensor with the specified name
|
||||
*
|
||||
* @param name Name of this binary sensor.
|
||||
*/
|
||||
explicit BinarySensor(const std::string &name);
|
||||
|
||||
/** Add a callback to be notified of state changes.
|
||||
*
|
||||
|
||||
@@ -3,12 +3,14 @@ import esphome.config_validation as cv
|
||||
|
||||
from esphome.components import sensor, binary_sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_CHANNELS,
|
||||
CONF_VALUE,
|
||||
CONF_TYPE,
|
||||
ICON_CHECK_CIRCLE_OUTLINE,
|
||||
CONF_BINARY_SENSOR,
|
||||
CONF_GROUP,
|
||||
STATE_CLASS_NONE,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["binary_sensor"]
|
||||
@@ -31,11 +33,12 @@ entry = {
|
||||
CONFIG_SCHEMA = cv.typed_schema(
|
||||
{
|
||||
CONF_GROUP: sensor.sensor_schema(
|
||||
BinarySensorMap,
|
||||
icon=ICON_CHECK_CIRCLE_OUTLINE,
|
||||
accuracy_decimals=0,
|
||||
state_class=STATE_CLASS_NONE,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BinarySensorMap),
|
||||
cv.Required(CONF_CHANNELS): cv.All(
|
||||
cv.ensure_list(entry), cv.Length(min=1)
|
||||
),
|
||||
@@ -47,8 +50,9 @@ CONFIG_SCHEMA = cv.typed_schema(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await sensor.register_sensor(var, config)
|
||||
|
||||
constant = SENSOR_MAP_TYPES[config[CONF_TYPE]]
|
||||
cg.add(var.set_sensor_type(constant))
|
||||
|
||||
@@ -65,7 +65,7 @@ void BL0940::update() {
|
||||
}
|
||||
|
||||
void BL0940::setup() {
|
||||
for (auto *i : BL0940_INIT) {
|
||||
for (auto i : BL0940_INIT) {
|
||||
this->write_array(i, 6);
|
||||
delay(1);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ from esphome.const import (
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_AMPERE,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_KILOWATT_HOURS,
|
||||
@@ -33,39 +35,38 @@ CONFIG_SCHEMA = (
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BL0940),
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE, STATE_CLASS_MEASUREMENT
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_AMPERE,
|
||||
accuracy_decimals=2,
|
||||
device_class=DEVICE_CLASS_CURRENT,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
UNIT_AMPERE,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_WATT,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_POWER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
UNIT_WATT, ICON_EMPTY, 0, DEVICE_CLASS_POWER, STATE_CLASS_MEASUREMENT
|
||||
),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_KILOWATT_HOURS,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_ENERGY,
|
||||
UNIT_KILOWATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
),
|
||||
cv.Optional(CONF_INTERNAL_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
STATE_CLASS_NONE,
|
||||
),
|
||||
cv.Optional(CONF_EXTERNAL_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
STATE_CLASS_NONE,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -167,7 +167,7 @@ void BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t es
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
|
||||
auto *descr = this->get_config_descriptor(param->reg_for_notify.handle);
|
||||
auto descr = this->get_config_descriptor(param->reg_for_notify.handle);
|
||||
if (descr == nullptr) {
|
||||
ESP_LOGW(TAG, "No descriptor found for notify of handle 0x%x", param->reg_for_notify.handle);
|
||||
break;
|
||||
@@ -252,17 +252,16 @@ float BLEClient::parse_char_value(uint8_t *value, uint16_t length) {
|
||||
}
|
||||
|
||||
BLEService *BLEClient::get_service(espbt::ESPBTUUID uuid) {
|
||||
for (auto *svc : this->services_) {
|
||||
for (auto svc : this->services_)
|
||||
if (svc->uuid == uuid)
|
||||
return svc;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BLEService *BLEClient::get_service(uint16_t uuid) { return this->get_service(espbt::ESPBTUUID::from_uint16(uuid)); }
|
||||
|
||||
BLECharacteristic *BLEClient::get_characteristic(espbt::ESPBTUUID service, espbt::ESPBTUUID chr) {
|
||||
auto *svc = this->get_service(service);
|
||||
auto svc = this->get_service(service);
|
||||
if (svc == nullptr)
|
||||
return nullptr;
|
||||
return svc->get_characteristic(chr);
|
||||
@@ -273,24 +272,19 @@ BLECharacteristic *BLEClient::get_characteristic(uint16_t service, uint16_t chr)
|
||||
}
|
||||
|
||||
BLEDescriptor *BLEClient::get_config_descriptor(uint16_t handle) {
|
||||
for (auto &svc : this->services_) {
|
||||
for (auto &chr : svc->characteristics) {
|
||||
if (chr->handle == handle) {
|
||||
for (auto &desc : chr->descriptors) {
|
||||
for (auto &svc : this->services_)
|
||||
for (auto &chr : svc->characteristics)
|
||||
if (chr->handle == handle)
|
||||
for (auto &desc : chr->descriptors)
|
||||
if (desc->uuid == espbt::ESPBTUUID::from_uint16(0x2902))
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BLECharacteristic *BLEService::get_characteristic(espbt::ESPBTUUID uuid) {
|
||||
for (auto &chr : this->characteristics) {
|
||||
for (auto &chr : this->characteristics)
|
||||
if (chr->uuid == uuid)
|
||||
return chr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -299,10 +293,10 @@ BLECharacteristic *BLEService::get_characteristic(uint16_t uuid) {
|
||||
}
|
||||
|
||||
BLEDescriptor *BLEClient::get_descriptor(espbt::ESPBTUUID service, espbt::ESPBTUUID chr, espbt::ESPBTUUID descr) {
|
||||
auto *svc = this->get_service(service);
|
||||
auto svc = this->get_service(service);
|
||||
if (svc == nullptr)
|
||||
return nullptr;
|
||||
auto *ch = svc->get_characteristic(chr);
|
||||
auto ch = svc->get_characteristic(chr);
|
||||
if (ch == nullptr)
|
||||
return nullptr;
|
||||
return ch->get_descriptor(descr);
|
||||
@@ -385,29 +379,24 @@ void BLECharacteristic::parse_descriptors() {
|
||||
}
|
||||
|
||||
BLEDescriptor *BLECharacteristic::get_descriptor(espbt::ESPBTUUID uuid) {
|
||||
for (auto &desc : this->descriptors) {
|
||||
for (auto &desc : this->descriptors)
|
||||
if (desc->uuid == uuid)
|
||||
return desc;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
BLEDescriptor *BLECharacteristic::get_descriptor(uint16_t uuid) {
|
||||
return this->get_descriptor(espbt::ESPBTUUID::from_uint16(uuid));
|
||||
}
|
||||
|
||||
void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size, esp_gatt_write_type_t write_type) {
|
||||
auto *client = this->service->client;
|
||||
void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size) {
|
||||
auto client = this->service->client;
|
||||
auto status = esp_ble_gattc_write_char(client->gattc_if, client->conn_id, this->handle, new_val_size, new_val,
|
||||
write_type, ESP_GATT_AUTH_REQ_NONE);
|
||||
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
ESP_LOGW(TAG, "Error sending write value to BLE gattc server, status=%d", status);
|
||||
}
|
||||
}
|
||||
|
||||
void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size) {
|
||||
write_value(new_val, new_val_size, ESP_GATT_WRITE_TYPE_NO_RSP);
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
} // namespace esphome
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ class BLECharacteristic {
|
||||
BLEDescriptor *get_descriptor(espbt::ESPBTUUID uuid);
|
||||
BLEDescriptor *get_descriptor(uint16_t uuid);
|
||||
void write_value(uint8_t *new_val, int16_t new_val_size);
|
||||
void write_value(uint8_t *new_val, int16_t new_val_size, esp_gatt_write_type_t write_type);
|
||||
BLEService *service;
|
||||
};
|
||||
|
||||
@@ -127,10 +126,9 @@ class BLEClient : public espbt::ESPBTClient, public Component {
|
||||
bool all_nodes_established_() {
|
||||
if (this->state() != espbt::ClientState::ESTABLISHED)
|
||||
return false;
|
||||
for (auto &node : nodes_) {
|
||||
for (auto &node : nodes_)
|
||||
if (node->node_state != espbt::ClientState::ESTABLISHED)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import ble_client, esp32_ble_tracker, output
|
||||
from esphome.components import output, ble_client, esp32_ble_tracker
|
||||
from esphome.const import CONF_ID, CONF_SERVICE_UUID
|
||||
|
||||
from .. import ble_client_ns
|
||||
|
||||
|
||||
DEPENDENCIES = ["ble_client"]
|
||||
|
||||
CONF_CHARACTERISTIC_UUID = "characteristic_uuid"
|
||||
CONF_REQUIRE_RESPONSE = "require_response"
|
||||
|
||||
BLEBinaryOutput = ble_client_ns.class_(
|
||||
"BLEBinaryOutput", output.BinaryOutput, ble_client.BLEClientNode, cg.Component
|
||||
@@ -20,7 +19,6 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Required(CONF_ID): cv.declare_id(BLEBinaryOutput),
|
||||
cv.Required(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Required(CONF_CHARACTERISTIC_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Optional(CONF_REQUIRE_RESPONSE, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
@@ -63,7 +61,7 @@ def to_code(config):
|
||||
config[CONF_CHARACTERISTIC_UUID]
|
||||
)
|
||||
cg.add(var.set_char_uuid128(uuid128))
|
||||
cg.add(var.set_require_response(config[CONF_REQUIRE_RESPONSE]))
|
||||
|
||||
yield output.register_output(var, config)
|
||||
yield ble_client.register_ble_node(var, config)
|
||||
yield cg.register_component(var, config)
|
||||
|
||||
@@ -32,7 +32,7 @@ void BLEBinaryOutput::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
|
||||
break;
|
||||
}
|
||||
|
||||
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
|
||||
auto chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
|
||||
if (chr == nullptr) {
|
||||
ESP_LOGW(TAG, "[%s] Characteristic not found.", this->char_uuid_.to_string().c_str());
|
||||
break;
|
||||
@@ -54,7 +54,7 @@ void BLEBinaryOutput::write_state(bool state) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
|
||||
auto chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
|
||||
if (chr == nullptr) {
|
||||
ESP_LOGW(TAG, "[%s] Characteristic not found. State update can not be written.",
|
||||
this->char_uuid_.to_string().c_str());
|
||||
@@ -63,11 +63,7 @@ void BLEBinaryOutput::write_state(bool state) {
|
||||
|
||||
uint8_t state_as_uint = (uint8_t) state;
|
||||
ESP_LOGV(TAG, "[%s] Write State: %d", this->char_uuid_.to_string().c_str(), state_as_uint);
|
||||
if (this->require_response_) {
|
||||
chr->write_value(&state_as_uint, sizeof(state_as_uint), ESP_GATT_WRITE_TYPE_RSP);
|
||||
} else {
|
||||
chr->write_value(&state_as_uint, sizeof(state_as_uint), ESP_GATT_WRITE_TYPE_NO_RSP);
|
||||
}
|
||||
chr->write_value(&state_as_uint, sizeof(state_as_uint));
|
||||
}
|
||||
|
||||
} // namespace ble_client
|
||||
|
||||
@@ -25,11 +25,9 @@ class BLEBinaryOutput : public output::BinaryOutput, public BLEClientNode, publi
|
||||
void set_char_uuid128(uint8_t *uuid) { this->char_uuid_ = espbt::ESPBTUUID::from_raw(uuid); }
|
||||
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
esp_ble_gattc_cb_param_t *param) override;
|
||||
void set_require_response(bool response) { this->require_response_ = response; }
|
||||
|
||||
protected:
|
||||
void write_state(bool state) override;
|
||||
bool require_response_;
|
||||
espbt::ESPBTUUID service_uuid_;
|
||||
espbt::ESPBTUUID char_uuid_;
|
||||
espbt::ClientState client_state_;
|
||||
|
||||
@@ -2,7 +2,9 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, ble_client, esp32_ble_tracker
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
STATE_CLASS_NONE,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_SERVICE_UUID,
|
||||
)
|
||||
@@ -29,11 +31,12 @@ BLESensorNotifyTrigger = ble_client_ns.class_(
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(
|
||||
BLESensor,
|
||||
accuracy_decimals=0,
|
||||
state_class=STATE_CLASS_NONE,
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLESensor),
|
||||
cv.Required(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Required(CONF_CHARACTERISTIC_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Optional(CONF_DESCRIPTOR_UUID): esp32_ble_tracker.bt_uuid,
|
||||
@@ -54,7 +57,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
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]))
|
||||
@@ -121,6 +124,7 @@ async def to_code(config):
|
||||
await cg.register_component(var, config)
|
||||
await ble_client.register_ble_node(var, config)
|
||||
cg.add(var.set_enable_notify(config[CONF_NOTIFY]))
|
||||
await sensor.register_sensor(var, config)
|
||||
for conf in config.get(CONF_ON_NOTIFY, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await ble_client.register_ble_node(trigger, config)
|
||||
|
||||
@@ -43,7 +43,7 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
|
||||
}
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
this->handle = 0;
|
||||
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
|
||||
auto chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
|
||||
if (chr == nullptr) {
|
||||
this->status_set_warning();
|
||||
this->publish_state(NAN);
|
||||
@@ -53,7 +53,7 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
|
||||
}
|
||||
this->handle = chr->handle;
|
||||
if (this->descr_uuid_.get_uuid().len > 0) {
|
||||
auto *descr = chr->get_descriptor(this->descr_uuid_);
|
||||
auto descr = chr->get_descriptor(this->descr_uuid_);
|
||||
if (descr == nullptr) {
|
||||
this->status_set_warning();
|
||||
this->publish_state(NAN);
|
||||
|
||||
@@ -7,6 +7,7 @@ from esphome.const import (
|
||||
CONF_IBEACON_MAJOR,
|
||||
CONF_IBEACON_MINOR,
|
||||
CONF_IBEACON_UUID,
|
||||
CONF_ID,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
@@ -29,9 +30,9 @@ def _validate(config):
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
binary_sensor.binary_sensor_schema(BLEPresenceDevice)
|
||||
.extend(
|
||||
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLEPresenceDevice),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
cv.Optional(CONF_IBEACON_MAJOR): cv.uint16_t,
|
||||
@@ -47,9 +48,10 @@ CONFIG_SCHEMA = cv.All(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await binary_sensor.new_binary_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await esp32_ble_tracker.register_ble_device(var, config)
|
||||
await binary_sensor.register_binary_sensor(var, config)
|
||||
|
||||
if CONF_MAC_ADDRESS in config:
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
||||
@@ -4,6 +4,7 @@ from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import (
|
||||
CONF_SERVICE_UUID,
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_DECIBEL,
|
||||
@@ -18,7 +19,6 @@ BLERSSISensor = ble_rssi_ns.class_(
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(
|
||||
BLERSSISensor,
|
||||
unit_of_measurement=UNIT_DECIBEL,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
@@ -26,6 +26,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLERSSISensor),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
}
|
||||
@@ -37,9 +38,10 @@ CONFIG_SCHEMA = cv.All(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await esp32_ble_tracker.register_ble_device(var, config)
|
||||
await sensor.register_sensor(var, config)
|
||||
|
||||
if CONF_MAC_ADDRESS in config:
|
||||
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import text_sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
@@ -13,13 +14,18 @@ BLEScanner = ble_scanner_ns.class_(
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
text_sensor.text_sensor_schema(BLEScanner)
|
||||
text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLEScanner),
|
||||
}
|
||||
)
|
||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await text_sensor.new_text_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await esp32_ble_tracker.register_ble_device(var, config)
|
||||
await text_sensor.register_text_sensor(var, config)
|
||||
|
||||
@@ -214,10 +214,9 @@ void BME280Component::update() {
|
||||
float BME280Component::read_temperature_(const uint8_t *data, int32_t *t_fine) {
|
||||
int32_t adc = ((data[3] & 0xFF) << 16) | ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
|
||||
adc >>= 4;
|
||||
if (adc == 0x80000) {
|
||||
if (adc == 0x80000)
|
||||
// temperature was disabled
|
||||
return NAN;
|
||||
}
|
||||
|
||||
const int32_t t1 = this->calibration_.t1;
|
||||
const int32_t t2 = this->calibration_.t2;
|
||||
@@ -234,10 +233,9 @@ float BME280Component::read_temperature_(const uint8_t *data, int32_t *t_fine) {
|
||||
float BME280Component::read_pressure_(const uint8_t *data, int32_t t_fine) {
|
||||
int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
|
||||
adc >>= 4;
|
||||
if (adc == 0x80000) {
|
||||
if (adc == 0x80000)
|
||||
// pressure was disabled
|
||||
return NAN;
|
||||
}
|
||||
const int64_t p1 = this->calibration_.p1;
|
||||
const int64_t p2 = this->calibration_.p2;
|
||||
const int64_t p3 = this->calibration_.p3;
|
||||
|
||||
@@ -95,7 +95,7 @@ void BME680Component::setup() {
|
||||
this->calibration_.t3 = cal1[3];
|
||||
|
||||
this->calibration_.h1 = cal2[2] << 4 | (cal2[1] & 0x0F);
|
||||
this->calibration_.h2 = cal2[0] << 4 | cal2[1] >> 4;
|
||||
this->calibration_.h2 = cal2[0] << 4 | cal2[1];
|
||||
this->calibration_.h3 = cal2[3];
|
||||
this->calibration_.h4 = cal2[4];
|
||||
this->calibration_.h5 = cal2[5];
|
||||
@@ -420,11 +420,10 @@ float BME680Component::calc_humidity_(uint16_t raw_humidity) {
|
||||
|
||||
calc_hum = var2 + (var3 + var4 * temp_comp) * var2 * var2;
|
||||
|
||||
if (calc_hum > 100.0f) {
|
||||
if (calc_hum > 100.0f)
|
||||
calc_hum = 100.0f;
|
||||
} else if (calc_hum < 0.0f) {
|
||||
else if (calc_hum < 0.0f)
|
||||
calc_hum = 0.0f;
|
||||
}
|
||||
|
||||
return calc_hum;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import text_sensor
|
||||
from esphome.const import CONF_ID, CONF_ICON
|
||||
from . import BME680BSECComponent, CONF_BME680_BSEC_ID
|
||||
|
||||
DEPENDENCIES = ["bme680_bsec"]
|
||||
@@ -13,8 +14,11 @@ TYPES = [CONF_IAQ_ACCURACY]
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_BME680_BSEC_ID): cv.use_id(BME680BSECComponent),
|
||||
cv.Optional(CONF_IAQ_ACCURACY): text_sensor.text_sensor_schema(
|
||||
icon=ICON_ACCURACY
|
||||
cv.Optional(CONF_IAQ_ACCURACY): text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(text_sensor.TextSensor),
|
||||
cv.Optional(CONF_ICON, default=ICON_ACCURACY): cv.icon,
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
@@ -23,7 +27,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)
|
||||
sens = cg.new_Pvariable(conf[CONF_ID])
|
||||
await text_sensor.register_text_sensor(sens, conf)
|
||||
cg.add(getattr(hub, f"set_{key}_text_sensor")(sens))
|
||||
|
||||
|
||||
|
||||
@@ -161,10 +161,9 @@ float BMP280Component::read_temperature_(int32_t *t_fine) {
|
||||
return NAN;
|
||||
int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
|
||||
adc >>= 4;
|
||||
if (adc == 0x80000) {
|
||||
if (adc == 0x80000)
|
||||
// temperature was disabled
|
||||
return NAN;
|
||||
}
|
||||
|
||||
const int32_t t1 = this->calibration_.t1;
|
||||
const int32_t t2 = this->calibration_.t2;
|
||||
@@ -184,10 +183,9 @@ float BMP280Component::read_pressure_(int32_t t_fine) {
|
||||
return NAN;
|
||||
int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
|
||||
adc >>= 4;
|
||||
if (adc == 0x80000) {
|
||||
if (adc == 0x80000)
|
||||
// pressure was disabled
|
||||
return NAN;
|
||||
}
|
||||
const int64_t p1 = this->calibration_.p1;
|
||||
const int64_t p2 = this->calibration_.p2;
|
||||
const int64_t p3 = this->calibration_.p3;
|
||||
|
||||
@@ -8,21 +8,16 @@ CODEOWNERS = ["@mvturnho", "@danielschramm"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
CONF_CAN_ID = "can_id"
|
||||
CONF_CAN_ID_MASK = "can_id_mask"
|
||||
CONF_USE_EXTENDED_ID = "use_extended_id"
|
||||
CONF_CANBUS_ID = "canbus_id"
|
||||
CONF_BIT_RATE = "bit_rate"
|
||||
CONF_ON_FRAME = "on_frame"
|
||||
|
||||
|
||||
def validate_id(config):
|
||||
if CONF_CAN_ID in config:
|
||||
id_value = config[CONF_CAN_ID]
|
||||
id_ext = config[CONF_USE_EXTENDED_ID]
|
||||
if not id_ext:
|
||||
if id_value > 0x7FF:
|
||||
raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
|
||||
return config
|
||||
def validate_id(id_value, id_ext):
|
||||
if not id_ext:
|
||||
if id_value > 0x7FF:
|
||||
raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
|
||||
|
||||
|
||||
def validate_raw_data(value):
|
||||
@@ -39,7 +34,7 @@ canbus_ns = cg.esphome_ns.namespace("canbus")
|
||||
CanbusComponent = canbus_ns.class_("CanbusComponent", cg.Component)
|
||||
CanbusTrigger = canbus_ns.class_(
|
||||
"CanbusTrigger",
|
||||
automation.Trigger.template(cg.std_vector.template(cg.uint8), cg.uint32),
|
||||
automation.Trigger.template(cg.std_vector.template(cg.uint8)),
|
||||
cg.Component,
|
||||
)
|
||||
CanSpeed = canbus_ns.enum("CAN_SPEED")
|
||||
@@ -72,21 +67,23 @@ CANBUS_SCHEMA = cv.Schema(
|
||||
cv.Optional(CONF_ON_FRAME): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
||||
cv.Required(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
|
||||
cv.Optional(CONF_CAN_ID_MASK, default=0x1FFFFFFF): cv.int_range(
|
||||
min=0, max=0x1FFFFFFF
|
||||
),
|
||||
cv.GenerateID(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
},
|
||||
validate_id,
|
||||
cv.Optional(CONF_ON_FRAME): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
||||
cv.GenerateID(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
CANBUS_SCHEMA.add_extra(validate_id)
|
||||
|
||||
|
||||
async def setup_canbus_core_(var, config):
|
||||
validate_id(config[CONF_CAN_ID], config[CONF_USE_EXTENDED_ID])
|
||||
await cg.register_component(var, config)
|
||||
cg.add(var.set_can_id([config[CONF_CAN_ID]]))
|
||||
cg.add(var.set_use_extended_id([config[CONF_USE_EXTENDED_ID]]))
|
||||
@@ -94,16 +91,12 @@ async def setup_canbus_core_(var, config):
|
||||
|
||||
for conf in config.get(CONF_ON_FRAME, []):
|
||||
can_id = conf[CONF_CAN_ID]
|
||||
can_id_mask = conf[CONF_CAN_ID_MASK]
|
||||
ext_id = conf[CONF_USE_EXTENDED_ID]
|
||||
trigger = cg.new_Pvariable(
|
||||
conf[CONF_TRIGGER_ID], var, can_id, can_id_mask, ext_id
|
||||
)
|
||||
validate_id(can_id, ext_id)
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var, can_id, ext_id)
|
||||
await cg.register_component(trigger, conf)
|
||||
await automation.build_automation(
|
||||
trigger,
|
||||
[(cg.std_vector.template(cg.uint8), "x"), (cg.uint32, "can_id")],
|
||||
conf,
|
||||
trigger, [(cg.std_vector.template(cg.uint8), "x")], conf
|
||||
)
|
||||
|
||||
|
||||
@@ -124,17 +117,18 @@ async def register_canbus(var, config):
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
},
|
||||
validate_id,
|
||||
key=CONF_DATA,
|
||||
),
|
||||
)
|
||||
async def canbus_action_to_code(config, action_id, template_arg, args):
|
||||
validate_id(config[CONF_CAN_ID], config[CONF_USE_EXTENDED_ID])
|
||||
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)
|
||||
cg.add(var.set_can_id(can_id))
|
||||
|
||||
use_extended_id = await cg.templatable(
|
||||
config[CONF_USE_EXTENDED_ID], args, cg.uint32
|
||||
)
|
||||
|
||||
@@ -56,15 +56,13 @@ void Canbus::add_trigger(CanbusTrigger *trigger) {
|
||||
|
||||
void Canbus::loop() {
|
||||
struct CanFrame can_message;
|
||||
// read all messages until queue is empty
|
||||
int message_counter = 0;
|
||||
while (this->read_message(&can_message) == canbus::ERROR_OK) {
|
||||
message_counter++;
|
||||
// readmessage
|
||||
if (this->read_message(&can_message) == canbus::ERROR_OK) {
|
||||
if (can_message.use_extended_id) {
|
||||
ESP_LOGD(TAG, "received can message (#%d) extended can_id=0x%x size=%d", message_counter, can_message.can_id,
|
||||
ESP_LOGD(TAG, "received can message extended can_id=0x%x size=%d", can_message.can_id,
|
||||
can_message.can_data_length_code);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "received can message (#%d) std can_id=0x%x size=%d", message_counter, can_message.can_id,
|
||||
ESP_LOGD(TAG, "received can message std can_id=0x%x size=%d", can_message.can_id,
|
||||
can_message.can_data_length_code);
|
||||
}
|
||||
|
||||
@@ -77,10 +75,9 @@ void Canbus::loop() {
|
||||
}
|
||||
|
||||
// fire all triggers
|
||||
for (auto *trigger : this->triggers_) {
|
||||
if ((trigger->can_id_ == (can_message.can_id & trigger->can_id_mask_)) &&
|
||||
(trigger->use_extended_id_ == can_message.use_extended_id)) {
|
||||
trigger->trigger(data, can_message.can_id);
|
||||
for (auto trigger : this->triggers_) {
|
||||
if ((trigger->can_id_ == can_message.can_id) && (trigger->use_extended_id_ == can_message.use_extended_id)) {
|
||||
trigger->trigger(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,19 +116,17 @@ template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public P
|
||||
std::vector<uint8_t> data_static_{};
|
||||
};
|
||||
|
||||
class CanbusTrigger : public Trigger<std::vector<uint8_t>, uint32_t>, public Component {
|
||||
class CanbusTrigger : public Trigger<std::vector<uint8_t>>, public Component {
|
||||
friend class Canbus;
|
||||
|
||||
public:
|
||||
explicit CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const std::uint32_t can_id_mask,
|
||||
const bool use_extended_id)
|
||||
: parent_(parent), can_id_(can_id), can_id_mask_(can_id_mask), use_extended_id_(use_extended_id){};
|
||||
explicit CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const bool use_extended_id)
|
||||
: parent_(parent), can_id_(can_id), use_extended_id_(use_extended_id){};
|
||||
void setup() override { this->parent_->add_trigger(this); }
|
||||
|
||||
protected:
|
||||
Canbus *parent_;
|
||||
uint32_t can_id_;
|
||||
uint32_t can_id_mask_;
|
||||
bool use_extended_id_;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_CHANNEL
|
||||
from esphome.const import CONF_CHANNEL, CONF_ID
|
||||
from . import cap1188_ns, CAP1188Component, CONF_CAP1188_ID
|
||||
|
||||
DEPENDENCIES = ["cap1188"]
|
||||
CAP1188Channel = cap1188_ns.class_("CAP1188Channel", binary_sensor.BinarySensor)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(CAP1188Channel).extend(
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CAP1188Channel),
|
||||
cv.GenerateID(CONF_CAP1188_ID): cv.use_id(CAP1188Component),
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=7),
|
||||
}
|
||||
@@ -16,7 +17,8 @@ CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(CAP1188Channel).extend(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await binary_sensor.new_binary_sensor(config)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await binary_sensor.register_binary_sensor(var, config)
|
||||
hub = await cg.get_variable(config[CONF_CAP1188_ID])
|
||||
cg.add(var.set_channel(config[CONF_CHANNEL]))
|
||||
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
#pragma once
|
||||
// Generated from https://github.com/esphome/esphome-webserver
|
||||
#include "esphome/core/hal.h"
|
||||
namespace esphome {
|
||||
|
||||
namespace captive_portal {
|
||||
|
||||
const uint8_t INDEX_GZ[] PROGMEM = {
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xdd, 0x58, 0x09, 0x6f, 0xdc, 0x36, 0x16, 0xfe, 0x2b,
|
||||
0xac, 0x92, 0x74, 0x34, 0x8d, 0xc5, 0xd1, 0x31, 0x97, 0x35, 0xd2, 0x14, 0x89, 0x37, 0x45, 0x0b, 0x24, 0x69, 0x00,
|
||||
0xbb, 0x5d, 0x14, 0x69, 0x00, 0x73, 0x24, 0x6a, 0xc4, 0x58, 0xa2, 0x54, 0x91, 0x9a, 0x23, 0x83, 0xd9, 0xdf, 0xde,
|
||||
0x47, 0x52, 0x73, 0x38, 0x6b, 0x2f, 0x90, 0x62, 0x8b, 0xa2, 0x4d, 0x6c, 0x9a, 0xc7, 0x3b, 0x3f, 0xf2, 0xf1, 0x3d,
|
||||
0x2a, 0xfa, 0x2a, 0xad, 0x12, 0xb9, 0xad, 0x29, 0xca, 0x65, 0x59, 0xcc, 0x23, 0xd5, 0xa2, 0x82, 0xf0, 0x65, 0x4c,
|
||||
0x39, 0x8c, 0x28, 0x49, 0xe7, 0x51, 0x49, 0x25, 0x41, 0x49, 0x4e, 0x1a, 0x41, 0x65, 0xfc, 0xd3, 0xcd, 0x77, 0xce,
|
||||
0x14, 0x0d, 0xe6, 0x51, 0xc1, 0xf8, 0x1d, 0x6a, 0x68, 0x11, 0xb3, 0xa4, 0xe2, 0x28, 0x6f, 0x68, 0x16, 0xa7, 0x44,
|
||||
0x92, 0x90, 0x95, 0x64, 0x49, 0x15, 0x81, 0x66, 0xe3, 0xa4, 0xa4, 0xf1, 0x8a, 0xd1, 0x75, 0x5d, 0x35, 0x12, 0x01,
|
||||
0xa5, 0xa4, 0x5c, 0xc6, 0xd6, 0x9a, 0xa5, 0x32, 0x8f, 0x53, 0xba, 0x62, 0x09, 0x75, 0xf4, 0xe0, 0x82, 0x71, 0x26,
|
||||
0x19, 0x29, 0x1c, 0x91, 0x90, 0x82, 0xc6, 0xde, 0x45, 0x2b, 0x68, 0xa3, 0x07, 0x64, 0x01, 0x63, 0x5e, 0x59, 0x20,
|
||||
0x52, 0x24, 0x0d, 0xab, 0x25, 0x52, 0xf6, 0xc6, 0x65, 0x95, 0xb6, 0x05, 0x9d, 0x67, 0x2d, 0x4f, 0x24, 0x03, 0x0b,
|
||||
0x84, 0xcd, 0xfb, 0xbb, 0x82, 0x4a, 0x44, 0xe3, 0x37, 0x44, 0xe6, 0xb8, 0x24, 0x1b, 0xdb, 0x74, 0x18, 0xb7, 0xfd,
|
||||
0x6f, 0x6c, 0xfe, 0xdc, 0x73, 0xdd, 0xfe, 0x85, 0x6e, 0xdc, 0xfe, 0x00, 0xfe, 0xce, 0x1a, 0x2a, 0xdb, 0x86, 0x23,
|
||||
0x62, 0xdf, 0x46, 0x35, 0x50, 0xa2, 0x34, 0xb6, 0x4a, 0xcf, 0xc7, 0xae, 0x3b, 0x45, 0xde, 0x25, 0xf6, 0x47, 0x8e,
|
||||
0xe7, 0xe1, 0xc0, 0xf1, 0x46, 0xc9, 0xc4, 0x19, 0x21, 0x6f, 0x08, 0x8d, 0xef, 0xe3, 0x11, 0x72, 0x3f, 0x59, 0x28,
|
||||
0x63, 0x45, 0x11, 0x5b, 0xbc, 0xe2, 0xd4, 0x42, 0x42, 0x36, 0xd5, 0x1d, 0x8d, 0xad, 0xa4, 0x6d, 0x1a, 0xf0, 0xee,
|
||||
0xaa, 0x2a, 0xaa, 0x06, 0xac, 0xfd, 0x95, 0xa3, 0x7b, 0xff, 0xbe, 0x58, 0x87, 0x6c, 0x08, 0x17, 0x59, 0xd5, 0x94,
|
||||
0xb1, 0xa5, 0x41, 0xb1, 0x9f, 0xee, 0xe8, 0x1e, 0xa9, 0xa6, 0x7f, 0xb6, 0xe8, 0x54, 0x0d, 0x5b, 0x32, 0x1e, 0x5b,
|
||||
0x9e, 0x8f, 0xbc, 0x29, 0xe8, 0xbd, 0xed, 0xef, 0x8f, 0xa0, 0x10, 0x05, 0x4a, 0xe7, 0x66, 0x65, 0xbf, 0xbf, 0x8d,
|
||||
0xc4, 0x6a, 0x89, 0x36, 0x65, 0xc1, 0x45, 0x6c, 0xe5, 0x52, 0xd6, 0xe1, 0x60, 0xb0, 0x5e, 0xaf, 0xf1, 0x3a, 0xc0,
|
||||
0x55, 0xb3, 0x1c, 0xf8, 0xae, 0xeb, 0x0e, 0x80, 0xc2, 0x42, 0x66, 0x7f, 0x2c, 0x7f, 0x68, 0xa1, 0x9c, 0xb2, 0x65,
|
||||
0x2e, 0x75, 0x7f, 0xfe, 0x74, 0xc7, 0xf7, 0x91, 0xa2, 0x98, 0xdf, 0x7e, 0x38, 0xd3, 0xd2, 0x9c, 0x69, 0xe1, 0xdf,
|
||||
0x12, 0xdb, 0x3a, 0xb8, 0xda, 0x7b, 0xa3, 0x8c, 0x9a, 0x10, 0x1f, 0xf9, 0xc8, 0xd5, 0xff, 0x7d, 0x47, 0xf5, 0xbb,
|
||||
0x91, 0xf3, 0xd9, 0x08, 0x9d, 0x8d, 0xe0, 0xaf, 0x02, 0xd0, 0x2f, 0xc7, 0xce, 0xe5, 0x91, 0xdf, 0x53, 0xeb, 0x2b,
|
||||
0xcf, 0x3d, 0x4d, 0x28, 0xa6, 0xef, 0xc7, 0xe7, 0x63, 0xc7, 0xff, 0x59, 0x11, 0x68, 0xf4, 0x8f, 0x5c, 0x8e, 0x9f,
|
||||
0x7b, 0x3f, 0x8f, 0xc9, 0x08, 0x8d, 0xba, 0x99, 0x91, 0xa3, 0xfa, 0xc7, 0x91, 0xd6, 0x85, 0x46, 0x2b, 0x20, 0x2b,
|
||||
0x9d, 0xb1, 0x33, 0x22, 0x01, 0x0a, 0x3a, 0xab, 0xa0, 0x07, 0xd3, 0x63, 0xe0, 0x3e, 0x9b, 0x73, 0x82, 0x4f, 0xbd,
|
||||
0xc1, 0xdc, 0xea, 0x87, 0x96, 0x75, 0x82, 0xa1, 0x3a, 0x87, 0x01, 0x7f, 0xac, 0xe0, 0xdc, 0x59, 0x56, 0x7f, 0x6f,
|
||||
0x7d, 0x2b, 0xc8, 0x8a, 0x5a, 0x71, 0x1c, 0x43, 0xa8, 0xb5, 0x25, 0x9c, 0x10, 0x5c, 0x54, 0x09, 0x51, 0x2c, 0x58,
|
||||
0x50, 0xd2, 0x24, 0xf9, 0xd7, 0x5f, 0xdb, 0xc7, 0xa5, 0x25, 0x95, 0xaf, 0x0a, 0xaa, 0xba, 0xe2, 0xe5, 0xf6, 0x86,
|
||||
0x2c, 0xdf, 0x42, 0x00, 0xd9, 0x16, 0x11, 0x2c, 0xa5, 0x56, 0xff, 0xbd, 0xfb, 0x01, 0x0b, 0xb9, 0x2d, 0x28, 0x4e,
|
||||
0x99, 0xa8, 0x0b, 0xb2, 0x8d, 0xad, 0x05, 0xc8, 0xba, 0xb3, 0xfa, 0x17, 0x19, 0x95, 0x49, 0x6e, 0x5b, 0x03, 0x08,
|
||||
0xb1, 0x8c, 0x2d, 0xf1, 0x47, 0x51, 0x71, 0xab, 0x8f, 0x65, 0x4e, 0xb9, 0x6d, 0x1f, 0x2c, 0x54, 0xf6, 0x71, 0xbd,
|
||||
0x64, 0x3f, 0xb4, 0x74, 0xb4, 0x41, 0x32, 0xa9, 0x42, 0x0e, 0xab, 0xe0, 0xbd, 0x38, 0xce, 0x2e, 0xaa, 0x74, 0xfb,
|
||||
0x88, 0x79, 0xb9, 0x67, 0x6c, 0x63, 0x9c, 0xd3, 0xe6, 0x86, 0x6e, 0xe0, 0xb8, 0xfc, 0x9b, 0x7d, 0xc7, 0xd0, 0x5b,
|
||||
0x2a, 0xd7, 0x55, 0x73, 0x27, 0x42, 0x64, 0x3d, 0x37, 0xe2, 0x66, 0x26, 0x42, 0x39, 0x26, 0xb5, 0xc0, 0xa2, 0x80,
|
||||
0xf0, 0xb7, 0xbd, 0x3e, 0xc4, 0x6a, 0x7d, 0xdf, 0x14, 0x83, 0xe2, 0x6d, 0x94, 0xb2, 0x15, 0x4a, 0x0a, 0x22, 0xe0,
|
||||
0xb8, 0x72, 0x23, 0xcb, 0x42, 0x87, 0xb8, 0xaa, 0x78, 0x02, 0xfc, 0x77, 0xb1, 0xf5, 0x00, 0x76, 0x2f, 0xb7, 0x3f,
|
||||
0xa4, 0x76, 0x4f, 0x00, 0x6a, 0xbd, 0x3e, 0x5e, 0x91, 0xa2, 0xa5, 0x28, 0x46, 0x32, 0x67, 0xe2, 0x64, 0xe2, 0xec,
|
||||
0x51, 0xb6, 0x5a, 0xdc, 0x01, 0x57, 0x06, 0xcb, 0xc2, 0xee, 0x5b, 0xc7, 0x38, 0x8e, 0x88, 0xb9, 0xe5, 0xac, 0x27,
|
||||
0xd6, 0x67, 0x36, 0x39, 0x05, 0xcd, 0xa4, 0x75, 0x16, 0xf0, 0x4f, 0x77, 0x70, 0x1b, 0xe1, 0x06, 0xf4, 0xf7, 0xf7,
|
||||
0xa7, 0xd9, 0x48, 0xd4, 0x84, 0x7f, 0xce, 0xaa, 0x6c, 0xd4, 0x81, 0x85, 0x55, 0x4f, 0x45, 0x17, 0x10, 0x9d, 0x74,
|
||||
0x0e, 0xc8, 0xb1, 0xff, 0x74, 0x07, 0x71, 0xa6, 0x8e, 0xce, 0xdd, 0x49, 0x68, 0x34, 0x00, 0x84, 0xe6, 0xb7, 0xfb,
|
||||
0x7e, 0xff, 0xe4, 0xce, 0x6f, 0x2d, 0x6d, 0xb6, 0xd7, 0xb4, 0xa0, 0x89, 0xac, 0x1a, 0xdb, 0x7a, 0x02, 0x9a, 0xe0,
|
||||
0x24, 0x68, 0xbf, 0xbf, 0xbf, 0x79, 0xf3, 0x3a, 0xae, 0x6c, 0xda, 0xbf, 0x78, 0x8c, 0x5a, 0xdd, 0xea, 0xef, 0xe1,
|
||||
0x56, 0xff, 0x4f, 0xdc, 0x53, 0xf7, 0x7a, 0xef, 0x03, 0xb0, 0x1a, 0xaf, 0x4f, 0x97, 0xbb, 0xba, 0x00, 0x9e, 0xc3,
|
||||
0x25, 0x72, 0x61, 0x3d, 0x17, 0xb6, 0x33, 0x1e, 0xf5, 0x41, 0x3d, 0xfc, 0x80, 0xe9, 0xfa, 0x7a, 0x86, 0x6b, 0x5a,
|
||||
0x1d, 0xd1, 0xf9, 0x37, 0xbb, 0x45, 0xb5, 0x71, 0x04, 0xfb, 0xc4, 0xf8, 0x32, 0x64, 0x3c, 0xa7, 0x0d, 0x93, 0x7b,
|
||||
0x30, 0x17, 0x6e, 0xfa, 0xba, 0x95, 0xbb, 0x9a, 0xa4, 0xa9, 0x5a, 0x19, 0xd5, 0x9b, 0x59, 0x06, 0x79, 0x41, 0x51,
|
||||
0xd2, 0xd0, 0xa3, 0xe5, 0xde, 0xac, 0xeb, 0x2b, 0x28, 0xbc, 0x1c, 0x3d, 0xdb, 0xab, 0x83, 0xb7, 0x93, 0xb0, 0x65,
|
||||
0x0e, 0x29, 0xd8, 0x92, 0x87, 0x09, 0xd8, 0x4d, 0x1b, 0xc3, 0x94, 0x91, 0x92, 0x15, 0xdb, 0x50, 0xc0, 0x65, 0xe8,
|
||||
0x40, 0xc2, 0x60, 0xd9, 0x7e, 0xd1, 0x4a, 0x59, 0x71, 0xd0, 0xdd, 0xa4, 0xb4, 0x09, 0xdd, 0x99, 0xe9, 0x38, 0x0d,
|
||||
0x49, 0x59, 0x2b, 0x42, 0x1c, 0x34, 0xb4, 0x9c, 0x2d, 0x48, 0x72, 0xb7, 0x6c, 0xaa, 0x96, 0xa7, 0x4e, 0xa2, 0x6e,
|
||||
0xeb, 0xf0, 0x89, 0x97, 0x91, 0x80, 0x26, 0xb3, 0x6e, 0x94, 0x65, 0xd9, 0x0c, 0x90, 0xa0, 0x8e, 0xb9, 0xfc, 0x42,
|
||||
0x1f, 0x0f, 0x15, 0xdb, 0x99, 0x99, 0xd8, 0x57, 0x13, 0xc6, 0x46, 0x48, 0x25, 0xcf, 0x66, 0x07, 0x77, 0xdc, 0x19,
|
||||
0xa4, 0x01, 0x01, 0x42, 0x6a, 0x88, 0x7f, 0x30, 0x73, 0x5f, 0x12, 0xc6, 0xcf, 0xad, 0x57, 0x67, 0x65, 0xd6, 0x85,
|
||||
0x2f, 0xc0, 0xa2, 0xd5, 0xe8, 0x20, 0x9e, 0x41, 0xa2, 0x32, 0xb9, 0x30, 0xf4, 0xc7, 0x6e, 0xbd, 0xd9, 0xe3, 0xee,
|
||||
0x8c, 0xec, 0x0e, 0xd4, 0x59, 0x41, 0x37, 0xb3, 0x8f, 0xad, 0x90, 0x2c, 0xdb, 0x3a, 0x5d, 0x2e, 0x0d, 0xe1, 0xbc,
|
||||
0x40, 0x0e, 0x5d, 0x00, 0x29, 0xa5, 0x7c, 0xa6, 0x75, 0x38, 0x4c, 0xd2, 0x52, 0x74, 0x38, 0x1d, 0xc5, 0xe8, 0x53,
|
||||
0x7a, 0x5f, 0xd6, 0xff, 0xa2, 0x56, 0xc7, 0x71, 0x57, 0x92, 0x06, 0x72, 0x8b, 0xb3, 0xa8, 0x00, 0xd3, 0x32, 0x74,
|
||||
0x26, 0xb0, 0x57, 0xdd, 0x94, 0x12, 0x06, 0x9e, 0x83, 0x99, 0xfa, 0x6e, 0x3a, 0xe0, 0xed, 0xd5, 0x1b, 0x24, 0xaa,
|
||||
0x82, 0xa5, 0x1d, 0x9d, 0x26, 0x41, 0xee, 0x11, 0x1e, 0x0f, 0xb6, 0x1b, 0xa9, 0xb9, 0x03, 0xd4, 0xc3, 0x6c, 0x4a,
|
||||
0x3c, 0xf7, 0x81, 0x1d, 0x49, 0xb3, 0xcc, 0x5f, 0x64, 0x47, 0xa4, 0x54, 0xaa, 0xdd, 0xb3, 0xee, 0x54, 0xf8, 0x43,
|
||||
0x10, 0x70, 0xd8, 0x1b, 0xe8, 0xef, 0x99, 0x8e, 0x8b, 0xdd, 0x99, 0x14, 0x7d, 0x52, 0xc3, 0xb6, 0x29, 0xec, 0x87,
|
||||
0x4e, 0xee, 0xb3, 0xe0, 0xea, 0x94, 0x09, 0x7b, 0x8f, 0x67, 0xc2, 0x1e, 0x52, 0xb5, 0xcb, 0xcb, 0x6a, 0x13, 0xf7,
|
||||
0x74, 0x4e, 0x1a, 0xc2, 0x4f, 0xef, 0x59, 0xf0, 0x0a, 0xf8, 0xff, 0x2f, 0x29, 0xee, 0x0f, 0xa7, 0xb7, 0x2f, 0x48,
|
||||
0x6d, 0x5f, 0x98, 0xd5, 0x8c, 0x77, 0xca, 0x79, 0xe8, 0x41, 0xfa, 0x62, 0x58, 0xb0, 0xa5, 0xf7, 0x67, 0x40, 0xfb,
|
||||
0xdf, 0x38, 0x06, 0x2f, 0xbc, 0x29, 0xbe, 0x44, 0xba, 0x31, 0x10, 0xe1, 0x60, 0x8a, 0x26, 0x57, 0x43, 0x3c, 0xf4,
|
||||
0x90, 0xaa, 0x9a, 0xc6, 0x68, 0x82, 0xa7, 0x40, 0x30, 0xc6, 0xc1, 0x04, 0x26, 0x90, 0xef, 0xe1, 0xd1, 0x6b, 0x3f,
|
||||
0xc0, 0xe3, 0x11, 0x50, 0xf9, 0x2e, 0x0e, 0x7c, 0x64, 0x68, 0xc7, 0xd8, 0x07, 0x71, 0x8a, 0x24, 0x28, 0x01, 0xe8,
|
||||
0x24, 0xc0, 0xee, 0x04, 0xc4, 0x8d, 0xb1, 0x7b, 0x89, 0xa7, 0x63, 0x34, 0xc5, 0x13, 0x80, 0x0e, 0x0f, 0x47, 0x85,
|
||||
0x33, 0xc2, 0x1e, 0x4c, 0x07, 0x63, 0x32, 0xc5, 0xc3, 0x00, 0xe9, 0xc6, 0xc0, 0x31, 0x01, 0x11, 0x0e, 0x76, 0xbd,
|
||||
0xd7, 0x01, 0xf6, 0x27, 0xa0, 0x77, 0x38, 0x7c, 0x01, 0x62, 0x2f, 0x87, 0xc8, 0xb4, 0x06, 0x5e, 0x50, 0x30, 0x7a,
|
||||
0x0c, 0x34, 0xff, 0x9f, 0x0b, 0x1a, 0x40, 0xe2, 0xa1, 0x00, 0x5f, 0x42, 0xec, 0x7a, 0x8a, 0xdf, 0xb4, 0x06, 0x37,
|
||||
0xcf, 0x43, 0xee, 0x1f, 0xc6, 0x2c, 0xf8, 0xe7, 0x62, 0xe6, 0x29, 0x04, 0xa0, 0x0b, 0xba, 0x41, 0x0e, 0xd2, 0x8d,
|
||||
0xd1, 0x0d, 0xcc, 0xd3, 0xab, 0x4b, 0x34, 0x05, 0xae, 0xf1, 0x14, 0x5d, 0xa2, 0x91, 0x42, 0x17, 0xd8, 0x87, 0x86,
|
||||
0xc9, 0x01, 0xa6, 0x2f, 0x84, 0x71, 0xf8, 0x37, 0x86, 0xf1, 0x31, 0x9f, 0xfe, 0xc6, 0x2e, 0xfd, 0x15, 0x57, 0x10,
|
||||
0x94, 0x63, 0xba, 0x0c, 0x8b, 0x06, 0xe6, 0x15, 0xaf, 0xaa, 0x28, 0x78, 0x94, 0x43, 0x35, 0x02, 0xef, 0x7a, 0x0f,
|
||||
0xb1, 0x34, 0xce, 0xbd, 0xf9, 0xbd, 0x2a, 0x1d, 0x28, 0xbd, 0x79, 0xa4, 0xd3, 0xf9, 0xfc, 0x26, 0xa7, 0xe8, 0xd5,
|
||||
0xf5, 0x3b, 0x78, 0x08, 0x16, 0x05, 0xe2, 0xd5, 0x1a, 0xde, 0x9b, 0x5b, 0x24, 0x2b, 0xf5, 0x82, 0xe7, 0x50, 0x2a,
|
||||
0xaa, 0x2e, 0x3c, 0x20, 0x50, 0x57, 0x2c, 0x60, 0x8c, 0xa3, 0x45, 0x33, 0x7f, 0x57, 0x50, 0x22, 0x28, 0x5a, 0xb2,
|
||||
0x15, 0x45, 0x4c, 0x42, 0x1d, 0x50, 0x52, 0x24, 0x99, 0x6a, 0x8e, 0x8c, 0x9a, 0xee, 0x6d, 0x25, 0x69, 0x88, 0xae,
|
||||
0xaa, 0x7a, 0xab, 0x85, 0x24, 0x39, 0xe1, 0x4b, 0x9a, 0x1e, 0x84, 0x29, 0xea, 0x6d, 0xd5, 0x36, 0xe8, 0x97, 0x17,
|
||||
0x6f, 0x5e, 0xab, 0x87, 0x36, 0x45, 0x4e, 0xa7, 0x6c, 0x23, 0xd1, 0x8f, 0x37, 0x2f, 0x50, 0x5b, 0xc3, 0xa6, 0x53,
|
||||
0x63, 0x5b, 0xb5, 0xa2, 0xcd, 0x1a, 0x2a, 0x4b, 0xaa, 0x48, 0x40, 0xb9, 0xa0, 0x52, 0x42, 0xa1, 0x21, 0x30, 0x94,
|
||||
0xce, 0xda, 0x13, 0x53, 0x75, 0x83, 0xbb, 0x20, 0x7e, 0xde, 0x95, 0xd7, 0x51, 0x1e, 0x18, 0xd7, 0xaf, 0x3b, 0x6a,
|
||||
0x70, 0x3d, 0x98, 0x47, 0xea, 0x39, 0x8d, 0x88, 0x7e, 0x84, 0xc4, 0x83, 0x35, 0xcb, 0x98, 0x7a, 0xb8, 0xcd, 0x23,
|
||||
0x5d, 0x8f, 0x2a, 0x09, 0xaa, 0x24, 0x32, 0x5f, 0x34, 0x74, 0xaf, 0xa0, 0x7c, 0x09, 0xaf, 0x64, 0xd8, 0x70, 0xa8,
|
||||
0x50, 0x12, 0x9a, 0x57, 0x05, 0x54, 0x40, 0xf1, 0xf5, 0xf5, 0x0f, 0xff, 0x52, 0x9f, 0x3f, 0xc0, 0xcf, 0x13, 0x27,
|
||||
0x3c, 0x29, 0x0c, 0xa3, 0xea, 0x74, 0x7c, 0xe3, 0xa1, 0xf9, 0x90, 0x51, 0xc3, 0x7b, 0x00, 0xfc, 0x4e, 0xef, 0x49,
|
||||
0x79, 0x77, 0x98, 0xec, 0x24, 0xe9, 0x5f, 0x5d, 0xd9, 0x1a, 0x26, 0xd1, 0x2e, 0x4a, 0x26, 0xe7, 0xd7, 0x60, 0x60,
|
||||
0x34, 0x30, 0x0b, 0xe0, 0x9c, 0x72, 0xc0, 0xd0, 0xe6, 0x1d, 0x0f, 0xec, 0xa8, 0x42, 0xec, 0x27, 0x8d, 0x98, 0xd9,
|
||||
0x60, 0xed, 0x65, 0x49, 0x65, 0x5e, 0xa5, 0xf1, 0xbb, 0x1f, 0xaf, 0x6f, 0x8e, 0x1e, 0x77, 0xb0, 0x52, 0x9e, 0x98,
|
||||
0x0f, 0x2c, 0x6d, 0x21, 0x59, 0x4d, 0x1a, 0xa9, 0xc5, 0x3a, 0x2a, 0xce, 0x0e, 0x1e, 0xe9, 0x75, 0xbd, 0x33, 0xda,
|
||||
0xa9, 0x8e, 0x71, 0x30, 0x47, 0x0f, 0xd9, 0x78, 0xd0, 0xfd, 0x99, 0x95, 0x03, 0x73, 0x14, 0x07, 0xe6, 0x5c, 0x0e,
|
||||
0xf4, 0xe7, 0xa7, 0xdf, 0x01, 0xf1, 0x69, 0xfc, 0xac, 0x8e, 0x12, 0x00, 0x00};
|
||||
|
||||
} // namespace captive_portal
|
||||
} // namespace esphome
|
||||
@@ -4,27 +4,60 @@
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/components/wifi/wifi_component.h"
|
||||
#include "captive_index.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace captive_portal {
|
||||
|
||||
static const char *const TAG = "captive_portal";
|
||||
|
||||
void CaptivePortal::handle_config(AsyncWebServerRequest *request) {
|
||||
AsyncResponseStream *stream = request->beginResponseStream("application/json");
|
||||
stream->addHeader("cache-control", "public, max-age=0, must-revalidate");
|
||||
stream->printf(R"({"name":"%s","aps":[{})", App.get_name().c_str());
|
||||
void CaptivePortal::handle_index(AsyncWebServerRequest *request) {
|
||||
AsyncResponseStream *stream = request->beginResponseStream("text/html");
|
||||
stream->print(F("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" "
|
||||
"content=\"width=device-width,initial-scale=1,user-scalable=no\"/><title>"));
|
||||
stream->print(App.get_name().c_str());
|
||||
stream->print(F("</title><link rel=\"stylesheet\" href=\"/stylesheet.css\">"));
|
||||
stream->print(F("<script>function c(l){document.getElementById('ssid').value=l.innerText||l.textContent; "
|
||||
"document.getElementById('psk').focus();}</script>"));
|
||||
stream->print(F("</head>"));
|
||||
stream->print(F("<body><div class=\"main\"><h1>WiFi Networks</h1>"));
|
||||
|
||||
if (request->hasArg("save")) {
|
||||
stream->print(F("<div class=\"info\">The ESP will now try to connect to the network...<br/>Please give it some "
|
||||
"time to connect.<br/>Note: Copy the changed network to your YAML file - the next OTA update will "
|
||||
"overwrite these settings.</div>"));
|
||||
}
|
||||
|
||||
for (auto &scan : wifi::global_wifi_component->get_scan_result()) {
|
||||
if (scan.get_is_hidden())
|
||||
continue;
|
||||
|
||||
// Assumes no " in ssid, possible unicode isses?
|
||||
stream->printf(R"(,{"ssid":"%s","rssi":%d,"lock":%d})", scan.get_ssid().c_str(), scan.get_rssi(),
|
||||
scan.get_with_auth());
|
||||
stream->print(F("<div class=\"network\" onclick=\"c(this)\"><a href=\"#\" class=\"network-left\">"));
|
||||
|
||||
if (scan.get_rssi() >= -50) {
|
||||
stream->print(F("<img src=\"/wifi-strength-4.svg\">"));
|
||||
} else if (scan.get_rssi() >= -65) {
|
||||
stream->print(F("<img src=\"/wifi-strength-3.svg\">"));
|
||||
} else if (scan.get_rssi() >= -85) {
|
||||
stream->print(F("<img src=\"/wifi-strength-2.svg\">"));
|
||||
} else {
|
||||
stream->print(F("<img src=\"/wifi-strength-1.svg\">"));
|
||||
}
|
||||
|
||||
stream->print(F("<span class=\"network-ssid\">"));
|
||||
stream->print(scan.get_ssid().c_str());
|
||||
stream->print(F("</span></a>"));
|
||||
if (scan.get_with_auth()) {
|
||||
stream->print(F("<img src=\"/lock.svg\">"));
|
||||
}
|
||||
stream->print(F("</div>"));
|
||||
}
|
||||
stream->print(F("]}"));
|
||||
|
||||
stream->print(F("<h3>WiFi Settings</h3><form method=\"GET\" action=\"/wifisave\"><input id=\"ssid\" name=\"ssid\" "
|
||||
"length=32 placeholder=\"SSID\"><br/><input id=\"psk\" name=\"psk\" length=64 type=\"password\" "
|
||||
"placeholder=\"Password\"><br/><br/><button type=\"submit\">Save</button></form><br><hr><br>"));
|
||||
stream->print(F("<h1>OTA Update</h1><form method=\"POST\" action=\"/update\" enctype=\"multipart/form-data\"><input "
|
||||
"type=\"file\" name=\"update\"><button type=\"submit\">Update</button></form>"));
|
||||
stream->print(F("</div></body></html>"));
|
||||
request->send(stream);
|
||||
}
|
||||
void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) {
|
||||
@@ -35,7 +68,7 @@ void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) {
|
||||
ESP_LOGI(TAG, " Password=" LOG_SECRET("'%s'"), psk.c_str());
|
||||
wifi::global_wifi_component->save_wifi_sta(ssid, psk);
|
||||
wifi::global_wifi_component->start_scanning();
|
||||
request->redirect("/?save");
|
||||
request->redirect("/?save=true");
|
||||
}
|
||||
|
||||
void CaptivePortal::setup() {}
|
||||
@@ -65,21 +98,44 @@ void CaptivePortal::start() {
|
||||
this->active_ = true;
|
||||
}
|
||||
|
||||
const char STYLESHEET_CSS[] PROGMEM =
|
||||
R"(*{box-sizing:inherit}div,input{padding:5px;font-size:1em}input{width:95%}body{text-align:center;font-family:sans-serif}button{border:0;border-radius:.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;padding:0}.main{text-align:left;display:inline-block;min-width:260px}.network{display:flex;justify-content:space-between;align-items:center}.network-left{display:flex;align-items:center}.network-ssid{margin-bottom:-7px;margin-left:10px}.info{border:1px solid;margin:10px 0;padding:15px 10px;color:#4f8a10;background-color:#dff2bf})";
|
||||
const char LOCK_SVG[] PROGMEM =
|
||||
R"(<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M12 17a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2 2 2 0 0 0 2 2m6-9a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h1V6a5 5 0 0 1 5-5 5 5 0 0 1 5 5v2h1m-6-5a3 3 0 0 0-3 3v2h6V6a3 3 0 0 0-3-3z"/></svg>)";
|
||||
|
||||
void CaptivePortal::handleRequest(AsyncWebServerRequest *req) {
|
||||
if (req->url() == "/") {
|
||||
AsyncWebServerResponse *response = req->beginResponse_P(200, "text/html", INDEX_GZ, sizeof(INDEX_GZ));
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
req->send(response);
|
||||
return;
|
||||
} else if (req->url() == "/config.json") {
|
||||
this->handle_config(req);
|
||||
this->handle_index(req);
|
||||
return;
|
||||
} else if (req->url() == "/wifisave") {
|
||||
this->handle_wifisave(req);
|
||||
return;
|
||||
} else if (req->url() == "/stylesheet.css") {
|
||||
req->send_P(200, "text/css", STYLESHEET_CSS);
|
||||
return;
|
||||
} else if (req->url() == "/lock.svg") {
|
||||
req->send_P(200, "image/svg+xml", LOCK_SVG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncResponseStream *stream = req->beginResponseStream("image/svg+xml");
|
||||
stream->print(F("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\"><path d=\"M12 3A18.9 18.9 0 0 "
|
||||
"0 .38 7C4.41 12.06 7.89 16.37 12 21.5L23.65 7C20.32 4.41 16.22 3 12 "));
|
||||
if (req->url() == "/wifi-strength-4.svg") {
|
||||
stream->print(F("3z"));
|
||||
} else {
|
||||
if (req->url() == "/wifi-strength-1.svg") {
|
||||
stream->print(F("3m0 2c3.07 0 6.09.86 8.71 2.45l-5.1 6.36a8.43 8.43 0 0 0-7.22-.01L3.27 7.4"));
|
||||
} else if (req->url() == "/wifi-strength-2.svg") {
|
||||
stream->print(F("3m0 2c3.07 0 6.09.86 8.71 2.45l-3.21 3.98a11.32 11.32 0 0 0-11 0L3.27 7.4"));
|
||||
} else if (req->url() == "/wifi-strength-3.svg") {
|
||||
stream->print(F("3m0 2c3.07 0 6.09.86 8.71 2.45l-1.94 2.43A13.6 13.6 0 0 0 12 8C9 8 6.68 9 5.21 9.84l-1.94-2."));
|
||||
}
|
||||
stream->print(F("4A16.94 16.94 0 0 1 12 5z"));
|
||||
}
|
||||
stream->print(F("\"/></svg>"));
|
||||
req->send(stream);
|
||||
}
|
||||
CaptivePortal::CaptivePortal(web_server_base::WebServerBase *base) : base_(base) { global_captive_portal = this; }
|
||||
float CaptivePortal::get_setup_priority() const {
|
||||
// Before WiFi
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user