1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-03 08:31:47 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Jesse Hills
9268ef7665 Print error in dump config if pn532 is marked failed. 2022-05-25 13:03:53 +12:00
1016 changed files with 9755 additions and 46653 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "ESPHome Dev", "name": "ESPHome Dev",
"image": "ghcr.io/esphome/esphome-lint:dev", "image": "esphome/esphome-lint:dev",
"postCreateCommand": [ "postCreateCommand": [
"script/devcontainer-post-create" "script/devcontainer-post-create"
], ],

View File

@@ -25,9 +25,10 @@ indent_size = 2
[*.{yaml,yml}] [*.{yaml,yml}]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
quote_type = double quote_type = single
# JSON # JSON
[*.json] [*.json]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2

1
.github/FUNDING.yml vendored
View File

@@ -1,4 +1,3 @@
---
# These are supported funding model platforms # These are supported funding model platforms
custom: https://www.nabucasa.com custom: https://www.nabucasa.com

View File

@@ -1,4 +1,3 @@
---
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: Issue Tracker - name: Issue Tracker
@@ -6,10 +5,7 @@ contact_links:
about: Please create bug reports in the dedicated issue tracker. about: Please create bug reports in the dedicated issue tracker.
- name: Feature Request Tracker - name: Feature Request Tracker
url: https://github.com/esphome/feature-requests url: https://github.com/esphome/feature-requests
about: | about: Please create feature requests in the dedicated feature request tracker.
Please create feature requests in the dedicated feature request tracker.
- name: Frequently Asked Question - name: Frequently Asked Question
url: https://esphome.io/guides/faq.html url: https://esphome.io/guides/faq.html
about: | about: Please view the FAQ for common questions and what to include in a bug report.
Please view the FAQ for common questions and what
to include in a bug report.

View File

@@ -1,6 +1,6 @@
# What does this implement/fix? # What does this implement/fix?
<!-- Quick description and explanation of changes --> Quick description and explanation of changes
## Types of changes ## Types of changes
@@ -18,7 +18,6 @@
- [ ] ESP32 - [ ] ESP32
- [ ] ESP32 IDF - [ ] ESP32 IDF
- [ ] ESP8266 - [ ] ESP8266
- [ ] RP2040
## Example entry for `config.yaml`: ## Example entry for `config.yaml`:
<!-- <!--

View File

@@ -1,15 +1,9 @@
---
version: 2 version: 2
updates: updates:
- package-ecosystem: pip - package-ecosystem: "pip"
directory: "/" directory: "/"
schedule: schedule:
interval: daily interval: "daily"
ignore: ignore:
# Hypotehsis is only used for testing and is updated quite often # Hypotehsis is only used for testing and is updated quite often
- dependency-name: hypothesis - dependency-name: hypothesis
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10

View File

@@ -1,61 +1,53 @@
---
name: CI for docker images name: CI for docker images
# Only run when docker paths change # Only run when docker paths change
# yamllint disable-line rule:truthy
on: on:
push: push:
branches: [dev, beta, release] branches: [dev, beta, release]
paths: paths:
- "docker/**" - 'docker/**'
- ".github/workflows/**" - '.github/workflows/**'
- "requirements*.txt" - 'requirements*.txt'
- "platformio.ini" - 'platformio.ini'
pull_request: pull_request:
paths: paths:
- "docker/**" - 'docker/**'
- ".github/workflows/**" - '.github/workflows/**'
- "requirements*.txt" - 'requirements*.txt'
- "platformio.ini" - 'platformio.ini'
permissions: permissions:
contents: read contents: read
packages: read packages: read
concurrency:
# yamllint disable-line rule:line-length
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs: jobs:
check-docker: check-docker:
name: Build docker containers name: Build docker containers
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false
matrix: matrix:
arch: [amd64, armv7, aarch64] arch: [amd64, armv7, aarch64]
build_type: ["ha-addon", "docker", "lint"] build_type: ["ha-addon", "docker", "lint"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v2
with: with:
python-version: "3.9" python-version: '3.9'
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v1
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v1
- name: Set TAG - name: Set TAG
run: | run: |
echo "TAG=check" >> $GITHUB_ENV echo "TAG=check" >> $GITHUB_ENV
- name: Run build - name: Run build
run: | run: |
docker/build.py \ docker/build.py \
--tag "${TAG}" \ --tag "${TAG}" \
--arch "${{ matrix.arch }}" \ --arch "${{ matrix.arch }}" \
--build-type "${{ matrix.build_type }}" \ --build-type "${{ matrix.build_type }}" \
build build

View File

@@ -1,19 +1,15 @@
---
name: CI name: CI
# yamllint disable-line rule:truthy
on: on:
push: push:
branches: [dev, beta, release] branches: [dev, beta, release]
pull_request: pull_request:
merge_group:
permissions: permissions:
contents: read contents: read
concurrency: concurrency:
# yamllint disable-line rule:line-length
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true cancel-in-progress: true
@@ -49,14 +45,6 @@ jobs:
file: tests/test5.yaml file: tests/test5.yaml
name: Test tests/test5.yaml name: Test tests/test5.yaml
pio_cache_key: test5 pio_cache_key: test5
- id: test
file: tests/test6.yaml
name: Test tests/test6.yaml
pio_cache_key: test6
- id: test
file: tests/test7.yaml
name: Test tests/test7.yaml
pio_cache_key: test7
- id: pytest - id: pytest
name: Run pytest name: Run pytest
- id: clang-format - id: clang-format
@@ -85,28 +73,24 @@ jobs:
name: Run script/clang-tidy for ESP32 IDF name: Run script/clang-tidy for ESP32 IDF
options: --environment esp32-idf-tidy --grep USE_ESP_IDF options: --environment esp32-idf-tidy --grep USE_ESP_IDF
pio_cache_key: tidyesp32-idf pio_cache_key: tidyesp32-idf
- id: yamllint
name: Run yamllint
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v2
id: python id: python
with: with:
python-version: "3.9" python-version: '3.8'
- name: Cache virtualenv - name: Cache virtualenv
uses: actions/cache@v3 uses: actions/cache@v2
with: with:
path: .venv path: .venv
# yamllint disable-line rule:line-length
key: venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements*.txt') }} key: venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements*.txt') }}
restore-keys: | restore-keys: |
venv-${{ steps.python.outputs.python-version }}- venv-${{ steps.python.outputs.python-version }}-
- name: Set up virtualenv - name: Set up virtualenv
# yamllint disable rule:line-length
run: | run: |
python -m venv .venv python -m venv .venv
source .venv/bin/activate source .venv/bin/activate
@@ -115,14 +99,12 @@ jobs:
pip install -e . pip install -e .
echo "$GITHUB_WORKSPACE/.venv/bin" >> $GITHUB_PATH echo "$GITHUB_WORKSPACE/.venv/bin" >> $GITHUB_PATH
echo "VIRTUAL_ENV=$GITHUB_WORKSPACE/.venv" >> $GITHUB_ENV echo "VIRTUAL_ENV=$GITHUB_WORKSPACE/.venv" >> $GITHUB_ENV
# yamllint enable rule:line-length
# Use per check platformio cache because checks use different parts # Use per check platformio cache because checks use different parts
- name: Cache platformio - name: Cache platformio
uses: actions/cache@v3 uses: actions/cache@v2
with: with:
path: ~/.platformio path: ~/.platformio
# yamllint disable-line rule:line-length
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }} key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
if: matrix.id == 'test' || matrix.id == 'clang-tidy' if: matrix.id == 'test' || matrix.id == 'clang-tidy'
@@ -149,7 +131,7 @@ jobs:
if: matrix.id == 'ci-custom' if: matrix.id == 'ci-custom'
- name: Lint Python - name: Lint Python
run: script/lint-python -a run: script/lint-python
if: matrix.id == 'lint-python' if: matrix.id == 'lint-python'
- run: esphome compile ${{ matrix.file }} - run: esphome compile ${{ matrix.file }}
@@ -163,9 +145,8 @@ jobs:
pytest -vv --tb=native tests pytest -vv --tb=native tests
if: matrix.id == 'pytest' if: matrix.id == 'pytest'
# Also run git-diff-index so that the step is marked as failed on # Also run git-diff-index so that the step is marked as failed on formatting errors,
# formatting errors, since clang-format doesn't do anything but # since clang-format doesn't do anything but change files if -i is passed.
# change files if -i is passed.
- name: Run clang-format - name: Run clang-format
run: | run: |
script/clang-format -i script/clang-format -i
@@ -180,24 +161,6 @@ jobs:
# Also cache libdeps, store them in a ~/.platformio subfolder # Also cache libdeps, store them in a ~/.platformio subfolder
PLATFORMIO_LIBDEPS_DIR: ~/.platformio/libdeps PLATFORMIO_LIBDEPS_DIR: ~/.platformio/libdeps
- name: Run yamllint
if: matrix.id == 'yamllint'
uses: frenck/action-yamllint@v1.4.0
- name: Suggested changes - name: Suggested changes
run: script/ci-suggest-changes run: script/ci-suggest-changes
# yamllint disable-line rule:line-length if: always() && (matrix.id == 'clang-tidy' || matrix.id == 'clang-format')
if: always() && (matrix.id == 'clang-tidy' || matrix.id == 'clang-format' || matrix.id == 'lint-python')
ci-status:
name: CI Status
runs-on: ubuntu-latest
needs: [ci]
if: always()
steps:
- name: Successful deploy
if: ${{ !(contains(needs.*.result, 'failure')) }}
run: exit 0
- name: Failing deploy
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1

View File

@@ -1,10 +1,8 @@
---
name: Lock name: Lock
# yamllint disable-line rule:truthy
on: on:
schedule: schedule:
- cron: "30 0 * * *" - cron: '30 0 * * *'
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@@ -18,7 +16,7 @@ jobs:
lock: lock:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/lock-threads@v4 - uses: dessant/lock-threads@v3
with: with:
pr-inactive-days: "1" pr-inactive-days: "1"
pr-lock-reason: "" pr-lock-reason: ""

View File

@@ -1,7 +1,5 @@
---
name: Publish Release name: Publish Release
# yamllint disable-line rule:truthy
on: on:
workflow_dispatch: workflow_dispatch:
release: release:
@@ -19,10 +17,9 @@ jobs:
outputs: outputs:
tag: ${{ steps.tag.outputs.tag }} tag: ${{ steps.tag.outputs.tag }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Get tag - name: Get tag
id: tag id: tag
# yamllint disable rule:line-length
run: | run: |
if [[ "$GITHUB_EVENT_NAME" = "release" ]]; then if [[ "$GITHUB_EVENT_NAME" = "release" ]]; then
TAG="${GITHUB_REF#refs/tags/}" TAG="${GITHUB_REF#refs/tags/}"
@@ -30,24 +27,19 @@ jobs:
TAG=$(cat esphome/const.py | sed -n -E "s/^__version__\s+=\s+\"(.+)\"$/\1/p") TAG=$(cat esphome/const.py | sed -n -E "s/^__version__\s+=\s+\"(.+)\"$/\1/p")
today="$(date --utc '+%Y%m%d')" today="$(date --utc '+%Y%m%d')"
TAG="${TAG}${today}" TAG="${TAG}${today}"
BRANCH=${GITHUB_REF#refs/heads/}
if [[ "$BRANCH" != "dev" ]]; then
TAG="${TAG}-${BRANCH}"
fi
fi fi
echo "tag=${TAG}" >> $GITHUB_OUTPUT echo "::set-output name=tag::${TAG}"
# yamllint enable rule:line-length
deploy-pypi: deploy-pypi:
name: Build and publish to PyPi name: Build and publish to PyPi
if: github.repository == 'esphome/esphome' && github.event_name == 'release' if: github.repository == 'esphome/esphome' && github.event_name == 'release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v1
with: with:
python-version: "3.x" python-version: '3.x'
- name: Set up python environment - name: Set up python environment
run: | run: |
script/setup script/setup
@@ -61,95 +53,102 @@ jobs:
run: twine upload dist/* run: twine upload dist/*
deploy-docker: deploy-docker:
name: Build and publish ESPHome ${{ matrix.image.title}} name: Build and publish docker containers
if: github.repository == 'esphome/esphome' if: github.repository == 'esphome/esphome'
permissions: permissions:
contents: read contents: read
packages: write packages: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
continue-on-error: ${{ matrix.image.title == 'lint' }}
needs: [init] needs: [init]
strategy: strategy:
fail-fast: false
matrix: matrix:
image: arch: [amd64, armv7, aarch64]
- title: "ha-addon" build_type: ["ha-addon", "docker", "lint"]
suffix: "hassio"
target: "hassio"
baseimg: "hassio"
- title: "docker"
suffix: ""
target: "docker"
baseimg: "docker"
- title: "lint"
suffix: "lint"
target: "lint"
baseimg: "docker"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v2
with: with:
python-version: "3.9" python-version: '3.9'
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v1
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v1
- name: Log in to docker hub - name: Log in to docker hub
uses: docker/login-action@v2 uses: docker/login-action@v1
with: with:
username: ${{ secrets.DOCKER_USER }} username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the GitHub container registry - name: Log in to the GitHub container registry
uses: docker/login-action@v2 uses: docker/login-action@v1
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate short tags - name: Build and push
id: tags run: |
run: | docker/build.py \
docker/generate_tags.py \ --tag "${{ needs.init.outputs.tag }}" \
--tag "${{ needs.init.outputs.tag }}" \ --arch "${{ matrix.arch }}" \
--suffix "${{ matrix.image.suffix }}" --build-type "${{ matrix.build_type }}" \
build \
--push
- name: Build and push deploy-docker-manifest:
uses: docker/build-push-action@v3 if: github.repository == 'esphome/esphome'
with: permissions:
context: . contents: read
file: ./docker/Dockerfile packages: write
platforms: linux/amd64,linux/arm/v7,linux/arm64 runs-on: ubuntu-latest
target: ${{ matrix.image.target }} needs: [init, deploy-docker]
push: true strategy:
# yamllint disable rule:line-length matrix:
cache-from: type=registry,ref=ghcr.io/${{ steps.tags.outputs.image }}:cache-${{ steps.tags.outputs.channel }} build_type: ["ha-addon", "docker", "lint"]
cache-to: type=registry,ref=ghcr.io/${{ steps.tags.outputs.image }}:cache-${{ steps.tags.outputs.channel }},mode=max steps:
# yamllint enable rule:line-length - uses: actions/checkout@v2
tags: ${{ steps.tags.outputs.tags }} - name: Set up Python
build-args: | uses: actions/setup-python@v2
BASEIMGTYPE=${{ matrix.image.baseimg }} with:
BUILD_VERSION=${{ needs.init.outputs.tag }} python-version: '3.9'
- name: Enable experimental manifest support
run: |
mkdir -p ~/.docker
echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json
- name: Log in to docker hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the GitHub container registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run manifest
run: |
docker/build.py \
--tag "${{ needs.init.outputs.tag }}" \
--build-type "${{ matrix.build_type }}" \
manifest
deploy-ha-addon-repo: deploy-ha-addon-repo:
if: github.repository == 'esphome/esphome' && github.event_name == 'release' if: github.repository == 'esphome/esphome' && github.event_name == 'release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [deploy-docker] needs: [deploy-docker]
steps: steps:
- name: Trigger Workflow - env:
uses: actions/github-script@v6 TOKEN: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
with: run: |
github-token: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }} TAG="${GITHUB_REF#refs/tags/}"
script: | curl \
github.rest.actions.createWorkflowDispatch({ -u ":$TOKEN" \
owner: "esphome", -X POST \
repo: "home-assistant-addon", -H "Accept: application/vnd.github.v3+json" \
workflow_id: "bump-version.yml", https://api.github.com/repos/esphome/home-assistant-addon/actions/workflows/bump-version.yml/dispatches \
ref: "main", -d "{\"ref\":\"main\",\"inputs\":{\"version\":\"$TAG\"}}"
inputs: {
version: "${{ github.event.release.tag_name }}",
content: ${{ toJSON(github.event.release.body) }}
}
})

View File

@@ -1,10 +1,8 @@
---
name: Stale name: Stale
# yamllint disable-line rule:truthy
on: on:
schedule: schedule:
- cron: "30 0 * * *" - cron: '30 0 * * *'
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@@ -18,7 +16,7 @@ jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v7 - uses: actions/stale@v4
with: with:
days-before-pr-stale: 90 days-before-pr-stale: 90
days-before-pr-close: 7 days-before-pr-close: 7
@@ -33,12 +31,11 @@ jobs:
and will be closed if no further activity occurs within 7 days. and will be closed if no further activity occurs within 7 days.
Thank you for your contributions. Thank you for your contributions.
# Use stale to automatically close issues with a # Use stale to automatically close issues with a reference to the issue tracker
# reference to the issue tracker
close-issues: close-issues:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v7 - uses: actions/stale@v4
with: with:
days-before-pr-stale: -1 days-before-pr-stale: -1
days-before-pr-close: -1 days-before-pr-close: -1

2
.gitignore vendored
View File

@@ -128,5 +128,3 @@ tests/.esphome/
sdkconfig.* sdkconfig.*
!sdkconfig.defaults !sdkconfig.defaults
.tests/

6
.gitpod.yml Normal file
View File

@@ -0,0 +1,6 @@
ports:
- port: 6052
onOpen: open-preview
tasks:
- before: pyenv local $(pyenv version | grep '^3\.' | cut -d ' ' -f 1) && script/setup
command: python -m esphome dashboard config

View File

@@ -1,17 +1,16 @@
---
# See https://pre-commit.com for more information # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
repos: repos:
- repo: https://github.com/ambv/black - repo: https://github.com/ambv/black
rev: 23.1.0 rev: 22.3.0
hooks: hooks:
- id: black - id: black
args: args:
- --safe - --safe
- --quiet - --quiet
files: ^((esphome|script|tests)/.+)?[^/]+\.py$ files: ^((esphome|script|tests)/.+)?[^/]+\.py$
- repo: https://github.com/PyCQA/flake8 - repo: https://gitlab.com/pycqa/flake8
rev: 6.0.0 rev: 4.0.1
hooks: hooks:
- id: flake8 - id: flake8
additional_dependencies: additional_dependencies:
@@ -27,7 +26,7 @@ repos:
- --branch=release - --branch=release
- --branch=beta - --branch=beta
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v3.3.1 rev: v2.31.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: [--py39-plus] args: [--py38-plus]

View File

@@ -1,3 +0,0 @@
---
ignore: |
venv/

View File

@@ -11,10 +11,8 @@ esphome/*.py @esphome/core
esphome/core/* @esphome/core esphome/core/* @esphome/core
# Integrations # Integrations
esphome/components/absolute_humidity/* @DAVe3283
esphome/components/ac_dimmer/* @glmnet esphome/components/ac_dimmer/* @glmnet
esphome/components/adc/* @esphome/core esphome/components/adc/* @esphome/core
esphome/components/adc128s102/* @DeerMaximum
esphome/components/addressable_light/* @justfalter esphome/components/addressable_light/* @justfalter
esphome/components/airthings_ble/* @jeromelaban esphome/components/airthings_ble/* @jeromelaban
esphome/components/airthings_wave_mini/* @ncareau esphome/components/airthings_wave_mini/* @ncareau
@@ -25,26 +23,19 @@ esphome/components/analog_threshold/* @ianchi
esphome/components/animation/* @syndlex esphome/components/animation/* @syndlex
esphome/components/anova/* @buxtronix esphome/components/anova/* @buxtronix
esphome/components/api/* @OttoWinter esphome/components/api/* @OttoWinter
esphome/components/as7341/* @mrgnr
esphome/components/async_tcp/* @OttoWinter esphome/components/async_tcp/* @OttoWinter
esphome/components/atc_mithermometer/* @ahpohl esphome/components/atc_mithermometer/* @ahpohl
esphome/components/b_parasite/* @rbaron esphome/components/b_parasite/* @rbaron
esphome/components/ballu/* @bazuchan esphome/components/ballu/* @bazuchan
esphome/components/bang_bang/* @OttoWinter esphome/components/bang_bang/* @OttoWinter
esphome/components/bedjet/* @jhansche esphome/components/bedjet/* @jhansche
esphome/components/bedjet/climate/* @jhansche
esphome/components/bedjet/fan/* @jhansche
esphome/components/bh1750/* @OttoWinter esphome/components/bh1750/* @OttoWinter
esphome/components/binary_sensor/* @esphome/core esphome/components/binary_sensor/* @esphome/core
esphome/components/bl0939/* @ziceva esphome/components/bl0939/* @ziceva
esphome/components/bl0940/* @tobias- esphome/components/bl0940/* @tobias-
esphome/components/bl0942/* @dbuezas
esphome/components/ble_client/* @buxtronix esphome/components/ble_client/* @buxtronix
esphome/components/bluetooth_proxy/* @jesserockz
esphome/components/bme680_bsec/* @trvrnrth esphome/components/bme680_bsec/* @trvrnrth
esphome/components/bmp3xx/* @martgras esphome/components/bmp3xx/* @martgras
esphome/components/bp1658cj/* @Cossid
esphome/components/bp5758d/* @Cossid
esphome/components/button/* @esphome/core esphome/components/button/* @esphome/core
esphome/components/canbus/* @danielschramm @mvturnho esphome/components/canbus/* @danielschramm @mvturnho
esphome/components/cap1188/* @MrEditor97 esphome/components/cap1188/* @MrEditor97
@@ -61,44 +52,32 @@ esphome/components/cs5460a/* @balrog-kun
esphome/components/cse7761/* @berfenger esphome/components/cse7761/* @berfenger
esphome/components/ct_clamp/* @jesserockz esphome/components/ct_clamp/* @jesserockz
esphome/components/current_based/* @djwmarcx esphome/components/current_based/* @djwmarcx
esphome/components/dac7678/* @NickB1
esphome/components/daikin_brc/* @hagak
esphome/components/daly_bms/* @s1lvi0 esphome/components/daly_bms/* @s1lvi0
esphome/components/dashboard_import/* @esphome/core esphome/components/dashboard_import/* @esphome/core
esphome/components/debug/* @OttoWinter esphome/components/debug/* @OttoWinter
esphome/components/delonghi/* @grob6000 esphome/components/delonghi/* @grob6000
esphome/components/dfplayer/* @glmnet esphome/components/dfplayer/* @glmnet
esphome/components/dht/* @OttoWinter esphome/components/dht/* @OttoWinter
esphome/components/display_menu_base/* @numo68
esphome/components/dps310/* @kbx81
esphome/components/ds1307/* @badbadc0ffee esphome/components/ds1307/* @badbadc0ffee
esphome/components/dsmr/* @glmnet @zuidwijk esphome/components/dsmr/* @glmnet @zuidwijk
esphome/components/ee895/* @Stock-M
esphome/components/ektf2232/* @jesserockz esphome/components/ektf2232/* @jesserockz
esphome/components/ens210/* @itn3rd77 esphome/components/ens210/* @itn3rd77
esphome/components/esp32/* @esphome/core esphome/components/esp32/* @esphome/core
esphome/components/esp32_ble/* @jesserockz esphome/components/esp32_ble/* @jesserockz
esphome/components/esp32_ble_client/* @jesserockz
esphome/components/esp32_ble_server/* @jesserockz esphome/components/esp32_ble_server/* @jesserockz
esphome/components/esp32_camera_web_server/* @ayufan esphome/components/esp32_camera_web_server/* @ayufan
esphome/components/esp32_can/* @Sympatron esphome/components/esp32_can/* @Sympatron
esphome/components/esp32_improv/* @jesserockz esphome/components/esp32_improv/* @jesserockz
esphome/components/esp8266/* @esphome/core esphome/components/esp8266/* @esphome/core
esphome/components/ethernet_info/* @gtjadsonsantos
esphome/components/exposure_notifications/* @OttoWinter esphome/components/exposure_notifications/* @OttoWinter
esphome/components/ezo/* @ssieb esphome/components/ezo/* @ssieb
esphome/components/ezo_pmp/* @carlos-sarmiento
esphome/components/factory_reset/* @anatoly-savchenkov
esphome/components/fastled_base/* @OttoWinter esphome/components/fastled_base/* @OttoWinter
esphome/components/feedback/* @ianchi
esphome/components/fingerprint_grow/* @OnFreund @loongyh esphome/components/fingerprint_grow/* @OnFreund @loongyh
esphome/components/fs3000/* @kahrendt
esphome/components/globals/* @esphome/core esphome/components/globals/* @esphome/core
esphome/components/gpio/* @esphome/core esphome/components/gpio/* @esphome/core
esphome/components/gps/* @coogle esphome/components/gps/* @coogle
esphome/components/graph/* @synco esphome/components/graph/* @synco
esphome/components/growatt_solar/* @leeuwte esphome/components/growatt_solar/* @leeuwte
esphome/components/haier/* @Yarikx
esphome/components/havells_solar/* @sourabhjaiswal esphome/components/havells_solar/* @sourabhjaiswal
esphome/components/hbridge/fan/* @WeekendWarrior esphome/components/hbridge/fan/* @WeekendWarrior
esphome/components/hbridge/light/* @DotNetDann esphome/components/hbridge/light/* @DotNetDann
@@ -107,34 +86,22 @@ esphome/components/hitachi_ac424/* @sourabhjaiswal
esphome/components/homeassistant/* @OttoWinter esphome/components/homeassistant/* @OttoWinter
esphome/components/honeywellabp/* @RubyBailey esphome/components/honeywellabp/* @RubyBailey
esphome/components/hrxl_maxsonar_wr/* @netmikey esphome/components/hrxl_maxsonar_wr/* @netmikey
esphome/components/hte501/* @Stock-M
esphome/components/hydreon_rgxx/* @functionpointer esphome/components/hydreon_rgxx/* @functionpointer
esphome/components/i2c/* @esphome/core esphome/components/i2c/* @esphome/core
esphome/components/i2s_audio/* @jesserockz
esphome/components/ili9xxx/* @nielsnl68
esphome/components/improv_base/* @esphome/core
esphome/components/improv_serial/* @esphome/core esphome/components/improv_serial/* @esphome/core
esphome/components/ina260/* @MrEditor97 esphome/components/ina260/* @MrEditor97
esphome/components/inkbird_ibsth1_mini/* @fkirill esphome/components/inkbird_ibsth1_mini/* @fkirill
esphome/components/inkplate6/* @jesserockz esphome/components/inkplate6/* @jesserockz
esphome/components/integration/* @OttoWinter esphome/components/integration/* @OttoWinter
esphome/components/internal_temperature/* @Mat931
esphome/components/interval/* @esphome/core esphome/components/interval/* @esphome/core
esphome/components/json/* @OttoWinter esphome/components/json/* @OttoWinter
esphome/components/kalman_combinator/* @Cat-Ion esphome/components/kalman_combinator/* @Cat-Ion
esphome/components/key_collector/* @ssieb
esphome/components/key_provider/* @ssieb
esphome/components/kuntze/* @ssieb
esphome/components/lcd_menu/* @numo68
esphome/components/ld2410/* @sebcaps
esphome/components/ledc/* @OttoWinter esphome/components/ledc/* @OttoWinter
esphome/components/light/* @esphome/core esphome/components/light/* @esphome/core
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
esphome/components/lock/* @esphome/core esphome/components/lock/* @esphome/core
esphome/components/logger/* @esphome/core esphome/components/logger/* @esphome/core
esphome/components/ltr390/* @sjtrny esphome/components/ltr390/* @sjtrny
esphome/components/matrix_keypad/* @ssieb
esphome/components/max31865/* @DAVe3283
esphome/components/max44009/* @berfenger esphome/components/max44009/* @berfenger
esphome/components/max7219digit/* @rspaargaren esphome/components/max7219digit/* @rspaargaren
esphome/components/max9611/* @mckaymatthew esphome/components/max9611/* @mckaymatthew
@@ -149,12 +116,9 @@ esphome/components/mcp2515/* @danielschramm @mvturnho
esphome/components/mcp3204/* @rsumner esphome/components/mcp3204/* @rsumner
esphome/components/mcp4728/* @berfenger esphome/components/mcp4728/* @berfenger
esphome/components/mcp47a1/* @jesserockz esphome/components/mcp47a1/* @jesserockz
esphome/components/mcp9600/* @MrEditor97
esphome/components/mcp9808/* @k7hpn esphome/components/mcp9808/* @k7hpn
esphome/components/md5/* @esphome/core esphome/components/md5/* @esphome/core
esphome/components/mdns/* @esphome/core esphome/components/mdns/* @esphome/core
esphome/components/media_player/* @jesserockz
esphome/components/mics_4514/* @jesserockz
esphome/components/midea/* @dudanov esphome/components/midea/* @dudanov
esphome/components/midea_ir/* @dudanov esphome/components/midea_ir/* @dudanov
esphome/components/mitsubishi/* @RubyBailey esphome/components/mitsubishi/* @RubyBailey
@@ -167,10 +131,8 @@ esphome/components/modbus_controller/select/* @martgras @stegm
esphome/components/modbus_controller/sensor/* @martgras esphome/components/modbus_controller/sensor/* @martgras
esphome/components/modbus_controller/switch/* @martgras esphome/components/modbus_controller/switch/* @martgras
esphome/components/modbus_controller/text_sensor/* @martgras esphome/components/modbus_controller/text_sensor/* @martgras
esphome/components/mopeka_ble/* @Fabian-Schmidt @spbrogan esphome/components/mopeka_ble/* @spbrogan
esphome/components/mopeka_pro_check/* @spbrogan esphome/components/mopeka_pro_check/* @spbrogan
esphome/components/mopeka_std_check/* @Fabian-Schmidt
esphome/components/mpl3115a2/* @kbickar
esphome/components/mpu6886/* @fabaff esphome/components/mpu6886/* @fabaff
esphome/components/network/* @esphome/core esphome/components/network/* @esphome/core
esphome/components/nextion/* @senexcrenshaw esphome/components/nextion/* @senexcrenshaw
@@ -182,8 +144,6 @@ esphome/components/nfc/* @jesserockz
esphome/components/number/* @esphome/core esphome/components/number/* @esphome/core
esphome/components/ota/* @esphome/core esphome/components/ota/* @esphome/core
esphome/components/output/* @esphome/core esphome/components/output/* @esphome/core
esphome/components/pca9554/* @hwstar
esphome/components/pcf85063/* @brogon
esphome/components/pid/* @OttoWinter esphome/components/pid/* @OttoWinter
esphome/components/pipsolar/* @andreashergert1984 esphome/components/pipsolar/* @andreashergert1984
esphome/components/pm1006/* @habbie esphome/components/pm1006/* @habbie
@@ -206,8 +166,6 @@ esphome/components/rc522_spi/* @glmnet
esphome/components/restart/* @esphome/core esphome/components/restart/* @esphome/core
esphome/components/rf_bridge/* @jesserockz esphome/components/rf_bridge/* @jesserockz
esphome/components/rgbct/* @jesserockz esphome/components/rgbct/* @jesserockz
esphome/components/rp2040/* @jesserockz
esphome/components/rp2040_pwm/* @jesserockz
esphome/components/rtttl/* @glmnet esphome/components/rtttl/* @glmnet
esphome/components/safe_mode/* @jsuanet @paulmonigatti esphome/components/safe_mode/* @jsuanet @paulmonigatti
esphome/components/scd4x/* @martgras @sjtrny esphome/components/scd4x/* @martgras @sjtrny
@@ -216,7 +174,6 @@ esphome/components/sdm_meter/* @jesserockz @polyfaces
esphome/components/sdp3x/* @Azimath esphome/components/sdp3x/* @Azimath
esphome/components/selec_meter/* @sourabhjaiswal esphome/components/selec_meter/* @sourabhjaiswal
esphome/components/select/* @esphome/core esphome/components/select/* @esphome/core
esphome/components/sen21231/* @shreyaskarnik
esphome/components/sen5x/* @martgras esphome/components/sen5x/* @martgras
esphome/components/sensirion_common/* @martgras esphome/components/sensirion_common/* @martgras
esphome/components/sensor/* @esphome/core esphome/components/sensor/* @esphome/core
@@ -225,19 +182,12 @@ esphome/components/sgp4x/* @SenexCrenshaw @martgras
esphome/components/shelly_dimmer/* @edge90 @rnauber esphome/components/shelly_dimmer/* @edge90 @rnauber
esphome/components/sht4x/* @sjtrny esphome/components/sht4x/* @sjtrny
esphome/components/shutdown/* @esphome/core @jsuanet esphome/components/shutdown/* @esphome/core @jsuanet
esphome/components/sigma_delta_output/* @Cat-Ion
esphome/components/sim800l/* @glmnet esphome/components/sim800l/* @glmnet
esphome/components/sm10bit_base/* @Cossid
esphome/components/sm2135/* @BoukeHaarsma23 esphome/components/sm2135/* @BoukeHaarsma23
esphome/components/sm2235/* @Cossid
esphome/components/sm2335/* @Cossid
esphome/components/sml/* @alengwenus esphome/components/sml/* @alengwenus
esphome/components/smt100/* @piechade
esphome/components/sn74hc165/* @jesserockz
esphome/components/socket/* @esphome/core esphome/components/socket/* @esphome/core
esphome/components/sonoff_d1/* @anatoly-savchenkov esphome/components/sonoff_d1/* @anatoly-savchenkov
esphome/components/spi/* @esphome/core esphome/components/spi/* @esphome/core
esphome/components/sprinkler/* @kbx81
esphome/components/sps30/* @martgras esphome/components/sps30/* @martgras
esphome/components/ssd1322_base/* @kbx81 esphome/components/ssd1322_base/* @kbx81
esphome/components/ssd1322_spi/* @kbx81 esphome/components/ssd1322_spi/* @kbx81
@@ -259,14 +209,11 @@ esphome/components/switch/* @esphome/core
esphome/components/t6615/* @tylermenezes esphome/components/t6615/* @tylermenezes
esphome/components/tca9548a/* @andreashergert1984 esphome/components/tca9548a/* @andreashergert1984
esphome/components/tcl112/* @glmnet esphome/components/tcl112/* @glmnet
esphome/components/tee501/* @Stock-M
esphome/components/teleinfo/* @0hax esphome/components/teleinfo/* @0hax
esphome/components/thermostat/* @kbx81 esphome/components/thermostat/* @kbx81
esphome/components/time/* @OttoWinter esphome/components/time/* @OttoWinter
esphome/components/tlc5947/* @rnauber esphome/components/tlc5947/* @rnauber
esphome/components/tm1621/* @Philippe12
esphome/components/tm1637/* @glmnet esphome/components/tm1637/* @glmnet
esphome/components/tm1638/* @skykingjwc
esphome/components/tmp102/* @timsavage esphome/components/tmp102/* @timsavage
esphome/components/tmp117/* @Azimath esphome/components/tmp117/* @Azimath
esphome/components/tof10120/* @wstrzalka esphome/components/tof10120/* @wstrzalka
@@ -281,20 +228,13 @@ esphome/components/tuya/sensor/* @jesserockz
esphome/components/tuya/switch/* @jesserockz esphome/components/tuya/switch/* @jesserockz
esphome/components/tuya/text_sensor/* @dentra esphome/components/tuya/text_sensor/* @dentra
esphome/components/uart/* @esphome/core esphome/components/uart/* @esphome/core
esphome/components/ufire_ec/* @pvizeli
esphome/components/ufire_ise/* @pvizeli
esphome/components/ultrasonic/* @OttoWinter esphome/components/ultrasonic/* @OttoWinter
esphome/components/vbus/* @ssieb
esphome/components/version/* @esphome/core esphome/components/version/* @esphome/core
esphome/components/wake_on_lan/* @willwill2will54 esphome/components/wake_on_lan/* @willwill2will54
esphome/components/web_server_base/* @OttoWinter esphome/components/web_server_base/* @OttoWinter
esphome/components/whirlpool/* @glmnet esphome/components/whirlpool/* @glmnet
esphome/components/whynter/* @aeonsablaze
esphome/components/wiegand/* @ssieb
esphome/components/wl_134/* @hobbypunk90
esphome/components/x9c/* @EtienneMD
esphome/components/xiaomi_lywsd03mmc/* @ahpohl esphome/components/xiaomi_lywsd03mmc/* @ahpohl
esphome/components/xiaomi_mhoc303/* @drug123 esphome/components/xiaomi_mhoc303/* @drug123
esphome/components/xiaomi_mhoc401/* @vevsvevs esphome/components/xiaomi_mhoc401/* @vevsvevs
esphome/components/xiaomi_rtcgq02lm/* @jesserockz esphome/components/xiaomi_rtcgq02lm/* @jesserockz
esphome/components/xpt2046/* @nielsnl68 @numo68 esphome/components/xpt2046/* @numo68

View File

@@ -1,6 +1,8 @@
include LICENSE include LICENSE
include README.md include README.md
include requirements.txt include requirements.txt
recursive-include esphome *.cpp *.h *.tcc *.c 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 *.py.script
recursive-include esphome LICENSE.txt recursive-include esphome LICENSE.txt

View File

@@ -6,14 +6,17 @@
ARG BASEIMGTYPE=docker ARG BASEIMGTYPE=docker
# https://github.com/hassio-addons/addon-debian-base/releases # https://github.com/hassio-addons/addon-debian-base/releases
FROM ghcr.io/hassio-addons/debian-base:6.2.3 AS base-hassio FROM ghcr.io/hassio-addons/debian-base/amd64:5.3.0 AS base-hassio-amd64
FROM ghcr.io/hassio-addons/debian-base/aarch64:5.3.0 AS base-hassio-arm64
FROM ghcr.io/hassio-addons/debian-base/armv7:5.3.0 AS base-hassio-armv7
# https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye # https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye
FROM debian:bullseye-20230208-slim AS base-docker FROM debian:bullseye-20220328-slim AS base-docker-amd64
FROM debian:bullseye-20220328-slim AS base-docker-arm64
FROM debian:bullseye-20220328-slim AS base-docker-armv7
FROM base-${BASEIMGTYPE} AS base # Use TARGETARCH/TARGETVARIANT defined by docker
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETARCH FROM base-${BASEIMGTYPE}-${TARGETARCH}${TARGETVARIANT} AS base
ARG TARGETVARIANT
RUN \ RUN \
apt-get update \ apt-get update \
@@ -26,8 +29,8 @@ RUN \
python3-cryptography=3.3.2-1 \ python3-cryptography=3.3.2-1 \
iputils-ping=3:20210202-1 \ iputils-ping=3:20210202-1 \
git=1:2.30.2-1 \ git=1:2.30.2-1 \
curl=7.74.0-1.3+deb11u7 \ curl=7.74.0-1.3+deb11u1 \
openssh-client=1:8.4p1-5+deb11u1 \ openssh-client=1:8.4p1-5 \
&& rm -rf \ && rm -rf \
/tmp/* \ /tmp/* \
/var/{cache,log}/* \ /var/{cache,log}/* \
@@ -39,22 +42,16 @@ ENV \
# Store globally installed pio libs in /piolibs # Store globally installed pio libs in /piolibs
PLATFORMIO_GLOBALLIB_DIR=/piolibs PLATFORMIO_GLOBALLIB_DIR=/piolibs
# Support legacy binaries on Debian multiarch system. There is no "correct" way
# to do this, other than using properly built toolchains...
# See: https://unix.stackexchange.com/questions/553743/correct-way-to-add-lib-ld-linux-so-3-in-debian
RUN \
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
ln -s /lib/arm-linux-gnueabihf/ld-linux.so.3 /lib/ld-linux.so.3; \
fi
RUN \ RUN \
# Ubuntu python3-pip is missing wheel # Ubuntu python3-pip is missing wheel
pip3 install --no-cache-dir \ pip3 install --no-cache-dir \
wheel==0.37.1 \ wheel==0.37.1 \
platformio==6.1.6 \ platformio==5.2.5 \
# Change some platformio settings # Change some platformio settings
&& platformio settings set enable_telemetry No \ && platformio settings set enable_telemetry No \
&& platformio settings set check_libraries_interval 1000000 \
&& platformio settings set check_platformio_interval 1000000 \ && platformio settings set check_platformio_interval 1000000 \
&& platformio settings set check_platforms_interval 1000000 \
&& mkdir -p /piolibs && mkdir -p /piolibs
@@ -99,7 +96,7 @@ RUN \
apt-get update \ apt-get update \
# Use pinned versions so that we get updates with build caching # Use pinned versions so that we get updates with build caching
&& apt-get install -y --no-install-recommends \ && apt-get install -y --no-install-recommends \
nginx-light=1.18.0-6.1+deb11u3 \ nginx-light=1.18.0-6.1 \
&& rm -rf \ && rm -rf \
/tmp/* \ /tmp/* \
/var/{cache,log}/* \ /var/{cache,log}/* \
@@ -139,7 +136,7 @@ RUN \
clang-tidy-11=1:11.0.1-2 \ clang-tidy-11=1:11.0.1-2 \
patch=2.7.6-7 \ patch=2.7.6-7 \
software-properties-common=0.96.20.2-2.1 \ software-properties-common=0.96.20.2-2.1 \
nano=5.4-2+deb11u2 \ nano=5.4-2 \
build-essential=12.9 \ build-essential=12.9 \
python3-dev=3.9.2-3 \ python3-dev=3.9.2-3 \
&& rm -rf \ && rm -rf \

View File

@@ -8,49 +8,32 @@ import re
import sys import sys
CHANNEL_DEV = "dev" CHANNEL_DEV = 'dev'
CHANNEL_BETA = "beta" CHANNEL_BETA = 'beta'
CHANNEL_RELEASE = "release" CHANNEL_RELEASE = 'release'
CHANNELS = [CHANNEL_DEV, CHANNEL_BETA, CHANNEL_RELEASE] CHANNELS = [CHANNEL_DEV, CHANNEL_BETA, CHANNEL_RELEASE]
ARCH_AMD64 = "amd64" ARCH_AMD64 = 'amd64'
ARCH_ARMV7 = "armv7" ARCH_ARMV7 = 'armv7'
ARCH_AARCH64 = "aarch64" ARCH_AARCH64 = 'aarch64'
ARCHS = [ARCH_AMD64, ARCH_ARMV7, ARCH_AARCH64] ARCHS = [ARCH_AMD64, ARCH_ARMV7, ARCH_AARCH64]
TYPE_DOCKER = "docker" TYPE_DOCKER = 'docker'
TYPE_HA_ADDON = "ha-addon" TYPE_HA_ADDON = 'ha-addon'
TYPE_LINT = "lint" TYPE_LINT = 'lint'
TYPES = [TYPE_DOCKER, TYPE_HA_ADDON, TYPE_LINT] TYPES = [TYPE_DOCKER, TYPE_HA_ADDON, TYPE_LINT]
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument("--tag", type=str, required=True, help="The main docker tag to push to. If a version number also adds latest and/or beta tag")
"--tag", parser.add_argument("--arch", choices=ARCHS, required=False, help="The architecture to build for")
type=str, parser.add_argument("--build-type", choices=TYPES, required=True, help="The type of build to run")
required=True, parser.add_argument("--dry-run", action="store_true", help="Don't run any commands, just print them")
help="The main docker tag to push to. If a version number also adds latest and/or beta tag", subparsers = parser.add_subparsers(help="Action to perform", dest="command", required=True)
)
parser.add_argument(
"--arch", choices=ARCHS, required=False, help="The architecture to build for"
)
parser.add_argument(
"--build-type", choices=TYPES, required=True, help="The type of build to run"
)
parser.add_argument(
"--dry-run", action="store_true", help="Don't run any commands, just print them"
)
subparsers = parser.add_subparsers(
help="Action to perform", dest="command", required=True
)
build_parser = subparsers.add_parser("build", help="Build the image") build_parser = subparsers.add_parser("build", help="Build the image")
build_parser.add_argument("--push", help="Also push the images", action="store_true") build_parser.add_argument("--push", help="Also push the images", action="store_true")
build_parser.add_argument( build_parser.add_argument("--load", help="Load the docker image locally", action="store_true")
"--load", help="Load the docker image locally", action="store_true" manifest_parser = subparsers.add_parser("manifest", help="Create a manifest from already pushed images")
)
manifest_parser = subparsers.add_parser(
"manifest", help="Create a manifest from already pushed images"
)
@dataclass(frozen=True) @dataclass(frozen=True)
@@ -66,7 +49,7 @@ class DockerParams:
prefix = { prefix = {
TYPE_DOCKER: "esphome/esphome", TYPE_DOCKER: "esphome/esphome",
TYPE_HA_ADDON: "esphome/esphome-hassio", TYPE_HA_ADDON: "esphome/esphome-hassio",
TYPE_LINT: "esphome/esphome-lint", TYPE_LINT: "esphome/esphome-lint"
}[build_type] }[build_type]
build_to = f"{prefix}-{arch}" build_to = f"{prefix}-{arch}"
baseimgtype = { baseimgtype = {
@@ -105,12 +88,10 @@ def main():
sys.exit(1) sys.exit(1)
# detect channel from tag # detect channel from tag
match = re.match(r"^(\d+\.\d+)(?:\.\d+)?(b\d+)?$", args.tag) match = re.match(r'^\d+\.\d+(?:\.\d+)?(b\d+)?$', args.tag)
major_minor_version = None
if match is None: if match is None:
channel = CHANNEL_DEV channel = CHANNEL_DEV
elif match.group(2) is None: elif match.group(1) is None:
major_minor_version = match.group(1)
channel = CHANNEL_RELEASE channel = CHANNEL_RELEASE
else: else:
channel = CHANNEL_BETA channel = CHANNEL_BETA
@@ -125,11 +106,6 @@ def main():
tags_to_push.append("beta") tags_to_push.append("beta")
tags_to_push.append("latest") tags_to_push.append("latest")
# Compatibility with HA tags
if major_minor_version:
tags_to_push.append("stable")
tags_to_push.append(major_minor_version)
if args.command == "build": if args.command == "build":
# 1. pull cache image # 1. pull cache image
params = DockerParams.for_type_arch(args.build_type, args.arch) params = DockerParams.for_type_arch(args.build_type, args.arch)
@@ -145,21 +121,13 @@ def main():
# 3. build # 3. build
cmd = [ cmd = [
"docker", "docker", "buildx", "build",
"buildx", "--build-arg", f"BASEIMGTYPE={params.baseimgtype}",
"build", "--build-arg", f"BUILD_VERSION={args.tag}",
"--build-arg", "--cache-from", f"type=registry,ref={cache_img}",
f"BASEIMGTYPE={params.baseimgtype}", "--file", "docker/Dockerfile",
"--build-arg", "--platform", params.platform,
f"BUILD_VERSION={args.tag}", "--target", params.target,
"--cache-from",
f"type=registry,ref={cache_img}",
"--file",
"docker/Dockerfile",
"--platform",
params.platform,
"--target",
params.target,
] ]
for img in imgs: for img in imgs:
cmd += ["--tag", img] cmd += ["--tag", img]
@@ -185,7 +153,9 @@ def main():
run_command(*cmd) run_command(*cmd)
# 2. Push manifests # 2. Push manifests
for target in targets: for target in targets:
run_command("docker", "manifest", "push", target) run_command(
"docker", "manifest", "push", target
)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -1,68 +0,0 @@
#!/usr/bin/env python3
import re
import os
import argparse
import json
CHANNEL_DEV = "dev"
CHANNEL_BETA = "beta"
CHANNEL_RELEASE = "release"
parser = argparse.ArgumentParser()
parser.add_argument(
"--tag",
type=str,
required=True,
help="The main docker tag to push to. If a version number also adds latest and/or beta tag",
)
parser.add_argument(
"--suffix",
type=str,
required=True,
help="The suffix of the tag.",
)
def main():
args = parser.parse_args()
# detect channel from tag
match = re.match(r"^(\d+\.\d+)(?:\.\d+)?(b\d+)?$", args.tag)
major_minor_version = None
if match is None:
channel = CHANNEL_DEV
elif match.group(2) is None:
major_minor_version = match.group(1)
channel = CHANNEL_RELEASE
else:
channel = CHANNEL_BETA
tags_to_push = [args.tag]
if channel == CHANNEL_DEV:
tags_to_push.append("dev")
elif channel == CHANNEL_BETA:
tags_to_push.append("beta")
elif channel == CHANNEL_RELEASE:
# Additionally push to beta
tags_to_push.append("beta")
tags_to_push.append("latest")
if major_minor_version:
tags_to_push.append("stable")
tags_to_push.append(major_minor_version)
suffix = f"-{args.suffix}" if args.suffix else ""
with open(os.environ["GITHUB_OUTPUT"], "w") as f:
print(f"channel={channel}", file=f)
print(f"image=esphome/esphome{suffix}", file=f)
full_tags = []
for tag in tags_to_push:
full_tags += [f"ghcr.io/esphome/esphome{suffix}:{tag}"]
full_tags += [f"esphome/esphome{suffix}:{tag}"]
print(f"tags={','.join(full_tags)}", file=f)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,41 @@
#!/usr/bin/with-contenv bashio
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files check if all user configuration requirements are met
# ==============================================================================
# Check SSL requirements, if enabled
if bashio::config.true 'ssl'; then
if ! bashio::config.has_value 'certfile'; then
bashio::log.fatal 'SSL is enabled, but no certfile was specified.'
bashio::exit.nok
fi
if ! bashio::config.has_value 'keyfile'; then
bashio::log.fatal 'SSL is enabled, but no keyfile was specified'
bashio::exit.nok
fi
certfile="/ssl/$(bashio::config 'certfile')"
keyfile="/ssl/$(bashio::config 'keyfile')"
if ! bashio::fs.file_exists "${certfile}"; then
if ! bashio::fs.file_exists "${keyfile}"; then
# Both files are missing, let's print a friendlier error message
bashio::log.fatal 'You enabled encrypted connections using the "ssl": true option.'
bashio::log.fatal "However, the SSL files '${certfile}' and '${keyfile}'"
bashio::log.fatal "were not found. If you're using Hass.io on your local network and don't want"
bashio::log.fatal 'to encrypt connections to the ESPHome dashboard, you can manually disable'
bashio::log.fatal 'SSL by setting "ssl" to false."'
bashio::exit.nok
fi
bashio::log.fatal "The configured certfile '${certfile}' was not found."
bashio::exit.nok
fi
if ! bashio::fs.file_exists "/ssl/$(bashio::config 'keyfile')"; then
bashio::log.fatal "The configured keyfile '${keyfile}' was not found."
bashio::exit.nok
fi
fi

View File

@@ -0,0 +1,34 @@
#!/usr/bin/with-contenv bashio
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Configures NGINX for use with ESPHome
# ==============================================================================
declare certfile
declare keyfile
declare direct_port
declare ingress_interface
declare ingress_port
mkdir -p /var/log/nginx
direct_port=$(bashio::addon.port 6052)
if bashio::var.has_value "${direct_port}"; then
if bashio::config.true 'ssl'; then
certfile=$(bashio::config 'certfile')
keyfile=$(bashio::config 'keyfile')
mv /etc/nginx/servers/direct-ssl.disabled /etc/nginx/servers/direct.conf
sed -i "s/%%certfile%%/${certfile}/g" /etc/nginx/servers/direct.conf
sed -i "s/%%keyfile%%/${keyfile}/g" /etc/nginx/servers/direct.conf
else
mv /etc/nginx/servers/direct.disabled /etc/nginx/servers/direct.conf
fi
sed -i "s/%%port%%/${direct_port}/g" /etc/nginx/servers/direct.conf
fi
ingress_port=$(bashio::addon.ingress_port)
ingress_interface=$(bashio::addon.ip_address)
sed -i "s/%%port%%/${ingress_port}/g" /etc/nginx/servers/ingress.conf
sed -i "s/%%interface%%/${ingress_interface}/g" /etc/nginx/servers/ingress.conf

View File

@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv bashio
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# This files creates all directories used by esphome
# ==============================================================================
pio_cache_base=/data/cache/platformio
mkdir -p "${pio_cache_base}"

View File

@@ -1,9 +1,9 @@
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_ignore_client_abort off; proxy_ignore_client_abort off;
proxy_read_timeout 86400s; proxy_read_timeout 86400s;
proxy_redirect off; proxy_redirect off;
proxy_send_timeout 86400s; proxy_send_timeout 86400s;
proxy_max_temp_file_size 0; proxy_max_temp_file_size 0;
proxy_set_header Accept-Encoding ""; proxy_set_header Accept-Encoding "";
proxy_set_header Connection $connection_upgrade; proxy_set_header Connection $connection_upgrade;

View File

@@ -1,7 +1,5 @@
root /dev/null; root /dev/null;
server_name $hostname; server_name $hostname;
client_max_body_size 512m;
add_header X-Content-Type-Options nosniff; add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block"; add_header X-XSS-Protection "1; mode=block";

View File

@@ -1,6 +1,7 @@
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers off; ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA;
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m; ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m; ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; ssl_session_tickets off;

View File

@@ -1,3 +0,0 @@
upstream esphome {
server unix:/var/run/esphome.sock;
}

View File

@@ -2,6 +2,7 @@ daemon off;
user root; user root;
pid /var/run/nginx.pid; pid /var/run/nginx.pid;
worker_processes 1; worker_processes 1;
# Hass.io addon log
error_log /proc/1/fd/1 error; error_log /proc/1/fd/1 error;
events { events {
worker_connections 1024; worker_connections 1024;
@@ -9,22 +10,24 @@ events {
http { http {
include /etc/nginx/includes/mime.types; include /etc/nginx/includes/mime.types;
access_log stdout;
access_log off; default_type application/octet-stream;
default_type application/octet-stream; gzip on;
gzip on; keepalive_timeout 65;
keepalive_timeout 65; sendfile on;
sendfile on; server_tokens off;
server_tokens off;
tcp_nodelay on;
tcp_nopush on;
map $http_upgrade $connection_upgrade { map $http_upgrade $connection_upgrade {
default upgrade; default upgrade;
'' close; '' close;
} }
include /etc/nginx/includes/upstream.conf; # Use Hass.io supervisor as resolver
resolver 172.30.32.2;
upstream esphome {
server unix:/var/run/esphome.sock;
}
include /etc/nginx/servers/*.conf; include /etc/nginx/servers/*.conf;
} }

View File

@@ -1 +0,0 @@
Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley)

View File

@@ -1,26 +1,20 @@
server { server {
{{ if not .ssl }} listen %%port%% default_server ssl http2;
listen 6052 default_server;
{{ else }}
listen 6052 default_server ssl http2;
{{ end }}
include /etc/nginx/includes/server_params.conf; include /etc/nginx/includes/server_params.conf;
include /etc/nginx/includes/proxy_params.conf; include /etc/nginx/includes/proxy_params.conf;
{{ if .ssl }}
include /etc/nginx/includes/ssl_params.conf; include /etc/nginx/includes/ssl_params.conf;
ssl_certificate /ssl/{{ .certfile }}; ssl on;
ssl_certificate_key /ssl/{{ .keyfile }}; ssl_certificate /ssl/%%certfile%%;
ssl_certificate_key /ssl/%%keyfile%%;
# Clear Hass.io Ingress header
proxy_set_header X-HA-Ingress "";
# Redirect http requests to https on the same port. # Redirect http requests to https on the same port.
# https://rageagainstshell.com/2016/11/redirect-http-to-https-on-the-same-port-in-nginx/ # https://rageagainstshell.com/2016/11/redirect-http-to-https-on-the-same-port-in-nginx/
error_page 497 https://$http_host$request_uri; error_page 497 https://$http_host$request_uri;
{{ end }}
# Clear Home Assistant Ingress header
proxy_set_header X-HA-Ingress "";
location / { location / {
proxy_pass http://esphome; proxy_pass http://esphome;

View File

@@ -0,0 +1,12 @@
server {
listen %%port%% default_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 "";
location / {
proxy_pass http://esphome;
}
}

View File

@@ -1,16 +1,14 @@
server { server {
listen 127.0.0.1:{{ .port }} default_server; listen %%interface%%:%%port%% default_server;
listen {{ .interface }}:{{ .port }} default_server;
include /etc/nginx/includes/server_params.conf; include /etc/nginx/includes/server_params.conf;
include /etc/nginx/includes/proxy_params.conf; include /etc/nginx/includes/proxy_params.conf;
# Set Home Assistant Ingress header # Set Home Assistant Ingress header
proxy_set_header X-HA-Ingress "YES"; proxy_set_header X-HA-Ingress "YES";
location / { location / {
# Only allow from Hass.io supervisor
allow 172.30.32.2; allow 172.30.32.2;
allow 127.0.0.1;
deny all; deny all;
proxy_pass http://esphome; proxy_pass http://esphome;

View File

@@ -1,32 +0,0 @@
#!/command/with-contenv bashio
# shellcheck shell=bash
# ==============================================================================
# Home Assistant Add-on: ESPHome
# Sends discovery information to Home Assistant.
# ==============================================================================
declare config
declare port
# We only disable it when disabled explicitly
if bashio::config.false 'home_assistant_dashboard_integration';
then
bashio::log.info "Home Assistant discovery is disabled for this add-on."
bashio::exit.ok
fi
port=$(bashio::addon.ingress_port)
# Wait for NGINX to become available
bashio::net.wait_for "${port}" "127.0.0.1" 300
config=$(\
bashio::var.json \
host "127.0.0.1" \
port "^${port}" \
)
if bashio::discovery "esphome" "${config}" > /dev/null; then
bashio::log.info "Successfully send discovery information to Home Assistant."
else
bashio::log.error "Discovery message to Home Assistant failed!"
fi

View File

@@ -1 +0,0 @@
/etc/s6-overlay/s6-rc.d/discovery/run

View File

@@ -1,26 +0,0 @@
#!/command/with-contenv bashio
# shellcheck shell=bash
# ==============================================================================
# Home Assistant Community Add-on: ESPHome
# Take down the S6 supervision tree when ESPHome dashboard fails
# ==============================================================================
declare exit_code
readonly exit_code_container=$(</run/s6-linux-init-container-results/exitcode)
readonly exit_code_service="${1}"
readonly exit_code_signal="${2}"
bashio::log.info \
"Service ESPHome dashboard exited with code ${exit_code_service}" \
"(by signal ${exit_code_signal})"
if [[ "${exit_code_service}" -eq 256 ]]; then
if [[ "${exit_code_container}" -eq 0 ]]; then
echo $((128 + $exit_code_signal)) > /run/s6-linux-init-container-results/exitcode
fi
[[ "${exit_code_signal}" -eq 15 ]] && exec /run/s6/basedir/bin/halt
elif [[ "${exit_code_service}" -ne 0 ]]; then
if [[ "${exit_code_container}" -eq 0 ]]; then
echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode
fi
exec /run/s6/basedir/bin/halt
fi

View File

@@ -1,27 +0,0 @@
#!/command/with-contenv bashio
# shellcheck shell=bash
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Configures NGINX for use with ESPHome
# ==============================================================================
mkdir -p /var/log/nginx
# Generate Ingress configuration
bashio::var.json \
interface "$(bashio::addon.ip_address)" \
port "^$(bashio::addon.ingress_port)" \
| tempio \
-template /etc/nginx/templates/ingress.gtpl \
-out /etc/nginx/servers/ingress.conf
# Generate direct access configuration, if enabled.
if bashio::var.has_value "$(bashio::addon.port 6052)"; then
bashio::config.require.ssl
bashio::var.json \
certfile "$(bashio::config 'certfile')" \
keyfile "$(bashio::config 'keyfile')" \
ssl "^$(bashio::config 'ssl')" \
| tempio \
-template /etc/nginx/templates/direct.gtpl \
-out /etc/nginx/servers/direct.conf
fi

View File

@@ -1 +0,0 @@
/etc/s6-overlay/s6-rc.d/init-nginx/run

View File

@@ -1,25 +0,0 @@
#!/command/with-contenv bashio
# ==============================================================================
# Community Hass.io Add-ons: ESPHome
# Take down the S6 supervision tree when NGINX fails
# ==============================================================================
declare exit_code
readonly exit_code_container=$(</run/s6-linux-init-container-results/exitcode)
readonly exit_code_service="${1}"
readonly exit_code_signal="${2}"
bashio::log.info \
"Service NGINX exited with code ${exit_code_service}" \
"(by signal ${exit_code_signal})"
if [[ "${exit_code_service}" -eq 256 ]]; then
if [[ "${exit_code_container}" -eq 0 ]]; then
echo $((128 + $exit_code_signal)) > /run/s6-linux-init-container-results/exitcode
fi
[[ "${exit_code_signal}" -eq 15 ]] && exec /run/s6/basedir/bin/halt
elif [[ "${exit_code_service}" -ne 0 ]]; then
if [[ "${exit_code_container}" -eq 0 ]]; then
echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode
fi
exec /run/s6/basedir/bin/halt
fi

View File

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

View File

@@ -1,19 +1,10 @@
#!/command/with-contenv bashio #!/usr/bin/with-contenv bashio
# shellcheck shell=bash
# ============================================================================== # ==============================================================================
# Community Hass.io Add-ons: ESPHome # Community Hass.io Add-ons: ESPHome
# Runs the ESPHome dashboard # Runs the ESPHome dashboard
# ============================================================================== # ==============================================================================
readonly pio_cache_base=/data/cache/platformio
export ESPHOME_IS_HA_ADDON=true export ESPHOME_IS_HA_ADDON=true
export PLATFORMIO_GLOBALLIB_DIR=/piolibs
# we can't set core_dir, because the settings file is stored in `core_dir/appstate.json`
# setting `core_dir` would therefore prevent pio from accessing
export PLATFORMIO_PLATFORMS_DIR="${pio_cache_base}/platforms"
export PLATFORMIO_PACKAGES_DIR="${pio_cache_base}/packages"
export PLATFORMIO_CACHE_DIR="${pio_cache_base}/cache"
if bashio::config.true 'leave_front_door_open'; then if bashio::config.true 'leave_front_door_open'; then
export DISABLE_HA_AUTHENTICATION=true export DISABLE_HA_AUTHENTICATION=true
@@ -31,15 +22,14 @@ if bashio::config.has_value 'relative_url'; then
export ESPHOME_DASHBOARD_RELATIVE_URL=$(bashio::config 'relative_url') export ESPHOME_DASHBOARD_RELATIVE_URL=$(bashio::config 'relative_url')
fi fi
if bashio::config.has_value 'default_compile_process_limit'; then pio_cache_base=/data/cache/platformio
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=$(bashio::config 'default_compile_process_limit') # we can't set core_dir, because the settings file is stored in `core_dir/appstate.json`
else # setting `core_dir` would therefore prevent pio from accessing
if grep -q 'Raspberry Pi 3' /proc/cpuinfo; then export PLATFORMIO_PLATFORMS_DIR="${pio_cache_base}/platforms"
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=1; export PLATFORMIO_PACKAGES_DIR="${pio_cache_base}/packages"
fi export PLATFORMIO_CACHE_DIR="${pio_cache_base}/cache"
fi
mkdir -p "${pio_cache_base}" export PLATFORMIO_GLOBALLIB_DIR=/piolibs
bashio::log.info "Starting ESPHome dashboard..." 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 --ha-addon

View File

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

View File

@@ -1,11 +1,10 @@
#!/command/with-contenv bashio #!/usr/bin/with-contenv bashio
# shellcheck shell=bash
# ============================================================================== # ==============================================================================
# Community Hass.io Add-ons: ESPHome # Community Hass.io Add-ons: ESPHome
# Runs the NGINX proxy # Runs the NGINX proxy
# ============================================================================== # ==============================================================================
bashio::log.info "Waiting for ESPHome dashboard to come up..." bashio::log.info "Waiting for dashboard to come up..."
while [[ ! -S /var/run/esphome.sock ]]; do while [[ ! -S /var/run/esphome.sock ]]; do
sleep 0.5 sleep 0.5

View File

@@ -4,7 +4,6 @@ import logging
import os import os
import re import re
import sys import sys
import time
from datetime import datetime from datetime import datetime
from esphome import const, writer, yaml_util from esphome import const, writer, yaml_util
@@ -23,9 +22,6 @@ from esphome.const import (
CONF_ESPHOME, CONF_ESPHOME,
CONF_PLATFORMIO_OPTIONS, CONF_PLATFORMIO_OPTIONS,
CONF_SUBSTITUTIONS, CONF_SUBSTITUTIONS,
PLATFORM_ESP32,
PLATFORM_ESP8266,
PLATFORM_RP2040,
SECRETS_FILES, SECRETS_FILES,
) )
from esphome.core import CORE, EsphomeError, coroutine from esphome.core import CORE, EsphomeError, coroutine
@@ -105,11 +101,11 @@ def run_miniterm(config, port):
if CONF_LOGGER not in config: if CONF_LOGGER not in config:
_LOGGER.info("Logger is not enabled. Not starting UART logs.") _LOGGER.info("Logger is not enabled. Not starting UART logs.")
return 1 return
baud_rate = config["logger"][CONF_BAUD_RATE] baud_rate = config["logger"][CONF_BAUD_RATE]
if baud_rate == 0: if baud_rate == 0:
_LOGGER.info("UART logging is disabled (baud_rate=0). Not starting UART logs.") _LOGGER.info("UART logging is disabled (baud_rate=0). Not starting UART logs.")
return 1 return
_LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate) _LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate)
backtrace_state = False backtrace_state = False
@@ -123,34 +119,25 @@ def run_miniterm(config, port):
ser.dtr = False ser.dtr = False
ser.rts = False ser.rts = False
tries = 0 with ser:
while tries < 5: while True:
try: try:
with ser: raw = ser.readline()
while True: except serial.SerialException:
try: _LOGGER.error("Serial port closed!")
raw = ser.readline() return
except serial.SerialException: line = (
_LOGGER.error("Serial port closed!") raw.replace(b"\r", b"")
return 0 .replace(b"\n", b"")
line = ( .decode("utf8", "backslashreplace")
raw.replace(b"\r", b"") )
.replace(b"\n", b"") time = datetime.now().time().strftime("[%H:%M:%S]")
.decode("utf8", "backslashreplace") message = time + line
) safe_print(message)
time_str = datetime.now().time().strftime("[%H:%M:%S]")
message = time_str + line
safe_print(message)
backtrace_state = platformio_api.process_stacktrace( backtrace_state = platformio_api.process_stacktrace(
config, line, backtrace_state=backtrace_state config, line, backtrace_state=backtrace_state
) )
except serial.SerialException:
tries += 1
time.sleep(1)
if tries >= 5:
_LOGGER.error("Could not connect to serial port %s", port)
return 1
def wrap_to_code(name, comp): def wrap_to_code(name, comp):
@@ -254,7 +241,8 @@ def upload_using_esptool(config, port):
if os.environ.get("ESPHOME_USE_SUBPROCESS") is None: if os.environ.get("ESPHOME_USE_SUBPROCESS") is None:
import esptool import esptool
return run_external_command(esptool.main, *cmd) # pylint: disable=no-member # pylint: disable=protected-access
return run_external_command(esptool._main, *cmd)
return run_external_process(*cmd) return run_external_process(*cmd)
@@ -270,21 +258,9 @@ def upload_using_esptool(config, port):
def upload_program(config, args, host): def upload_program(config, args, host):
# if upload is to a serial port use platformio, otherwise assume ota
if get_port_type(host) == "SERIAL": if get_port_type(host) == "SERIAL":
if CORE.target_platform in (PLATFORM_ESP32, PLATFORM_ESP8266): return upload_using_esptool(config, host)
return upload_using_esptool(config, host)
if CORE.target_platform in (PLATFORM_RP2040):
from esphome import platformio_api
upload_args = ["-t", "upload"]
if args.device is not None:
upload_args += ["--upload-port", args.device]
return platformio_api.run_platformio_cli_run(
config, CORE.verbose, *upload_args
)
return 1 # Unknown target platform
from esphome import espota2 from esphome import espota2
@@ -297,8 +273,6 @@ def upload_program(config, args, host):
ota_conf = config[CONF_OTA] ota_conf = config[CONF_OTA]
remote_port = ota_conf[CONF_PORT] remote_port = ota_conf[CONF_PORT]
password = ota_conf.get(CONF_PASSWORD, "") password = ota_conf.get(CONF_PASSWORD, "")
if getattr(args, "file", None) is not None:
return espota2.run_ota(host, remote_port, password, args.file)
return espota2.run_ota(host, remote_port, password, CORE.firmware_bin) return espota2.run_ota(host, remote_port, password, CORE.firmware_bin)
@@ -306,7 +280,8 @@ def show_logs(config, args, port):
if "logger" not in config: if "logger" not in config:
raise EsphomeError("Logger is not configured!") raise EsphomeError("Logger is not configured!")
if get_port_type(port) == "SERIAL": if get_port_type(port) == "SERIAL":
return run_miniterm(config, port) run_miniterm(config, port)
return 0
if get_port_type(port) == "NETWORK" and "api" in config: if get_port_type(port) == "NETWORK" and "api" in config:
from esphome.components.api.client import run_logs from esphome.components.api.client import run_logs
@@ -339,7 +314,7 @@ def command_config(args, config):
_LOGGER.info("Configuration is valid!") _LOGGER.info("Configuration is valid!")
if not CORE.verbose: if not CORE.verbose:
config = strip_default_ids(config) config = strip_default_ids(config)
safe_print(yaml_util.dump(config, args.show_secrets)) safe_print(yaml_util.dump(config))
return 0 return 0
@@ -665,9 +640,6 @@ def parse_args(argv):
parser_config.add_argument( parser_config.add_argument(
"configuration", help="Your YAML configuration file(s).", nargs="+" "configuration", help="Your YAML configuration file(s).", nargs="+"
) )
parser_config.add_argument(
"--show-secrets", help="Show secrets in output.", action="store_true"
)
parser_compile = subparsers.add_parser( parser_compile = subparsers.add_parser(
"compile", help="Read the configuration and compile a program." "compile", help="Read the configuration and compile a program."
@@ -691,10 +663,6 @@ def parse_args(argv):
"--device", "--device",
help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.", help="Manually specify the serial port/address to use, for example /dev/ttyUSB0.",
) )
parser_upload.add_argument(
"--file",
help="Manually specify the binary file to upload.",
)
parser_logs = subparsers.add_parser( parser_logs = subparsers.add_parser(
"logs", "logs",

View File

@@ -12,7 +12,7 @@ from esphome.const import (
CONF_TYPE_ID, CONF_TYPE_ID,
CONF_TIME, CONF_TIME,
) )
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor from esphome.jsonschema import jschema_extractor
from esphome.util import Registry from esphome.util import Registry
@@ -23,10 +23,11 @@ def maybe_simple_id(*validators):
def maybe_conf(conf, *validators): def maybe_conf(conf, *validators):
validator = cv.All(*validators) validator = cv.All(*validators)
@schema_extractor("maybe") @jschema_extractor("maybe")
def validate(value): def validate(value):
if value == SCHEMA_EXTRACT: # pylint: disable=comparison-with-callable
return (validator, conf) if value == jschema_extractor:
return validator
if isinstance(value, dict): if isinstance(value, dict):
return validator(value) return validator(value)
@@ -110,9 +111,11 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
# This should only happen with invalid configs, but let's have a nice error message. # This should only happen with invalid configs, but let's have a nice error message.
return [schema(value)] return [schema(value)]
@schema_extractor("automation") @jschema_extractor("automation")
def validator(value): def validator(value):
if value == SCHEMA_EXTRACT: # hack to get the schema
# pylint: disable=comparison-with-callable
if value == jschema_extractor:
return schema return schema
value = validator_(value) value = validator_(value)
@@ -254,11 +257,7 @@ async def repeat_action_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg) var = cg.new_Pvariable(action_id, template_arg)
count_template = await cg.templatable(config[CONF_COUNT], args, cg.uint32) count_template = await cg.templatable(config[CONF_COUNT], args, cg.uint32)
cg.add(var.set_count(count_template)) cg.add(var.set_count(count_template))
actions = await build_action_list( actions = await build_action_list(config[CONF_THEN], template_arg, args)
config[CONF_THEN],
cg.TemplateArguments(cg.uint32, *template_arg.args),
[(cg.uint32, "iteration"), *args],
)
cg.add(var.add_then(actions)) cg.add(var.add_then(actions))
return var return var

View File

@@ -22,7 +22,6 @@ from esphome.cpp_generator import ( # noqa
static_const_array, static_const_array,
statement, statement,
variable, variable,
with_local_variable,
new_variable, new_variable,
Pvariable, Pvariable,
new_Pvariable, new_Pvariable,
@@ -47,7 +46,6 @@ from esphome.cpp_helpers import ( # noqa
build_registry_list, build_registry_list,
extract_registry_entry_config, extract_registry_entry_config,
register_parented, register_parented,
past_safe_mode,
) )
from esphome.cpp_types import ( # noqa from esphome.cpp_types import ( # noqa
global_ns, global_ns,
@@ -64,7 +62,6 @@ from esphome.cpp_types import ( # noqa
uint16, uint16,
uint32, uint32,
uint64, uint64,
int16,
int32, int32,
int64, int64,
size_t, size_t,

View File

@@ -46,7 +46,6 @@ void A4988::loop() {
return; return;
this->dir_pin_->digital_write(dir == 1); this->dir_pin_->digital_write(dir == 1);
delayMicroseconds(50);
this->step_pin_->digital_write(true); this->step_pin_->digital_write(true);
delayMicroseconds(5); delayMicroseconds(5);
this->step_pin_->digital_write(false); this->step_pin_->digital_write(false);

View File

@@ -1 +0,0 @@
CODEOWNERS = ["@DAVe3283"]

View File

@@ -1,182 +0,0 @@
#include "esphome/core/log.h"
#include "absolute_humidity.h"
namespace esphome {
namespace absolute_humidity {
static const char *const TAG = "absolute_humidity.sensor";
void AbsoluteHumidityComponent::setup() {
ESP_LOGCONFIG(TAG, "Setting up absolute humidity '%s'...", this->get_name().c_str());
ESP_LOGD(TAG, " Added callback for temperature '%s'", this->temperature_sensor_->get_name().c_str());
this->temperature_sensor_->add_on_state_callback([this](float state) { this->temperature_callback_(state); });
if (this->temperature_sensor_->has_state()) {
this->temperature_callback_(this->temperature_sensor_->get_state());
}
ESP_LOGD(TAG, " Added callback for relative humidity '%s'", this->humidity_sensor_->get_name().c_str());
this->humidity_sensor_->add_on_state_callback([this](float state) { this->humidity_callback_(state); });
if (this->humidity_sensor_->has_state()) {
this->humidity_callback_(this->humidity_sensor_->get_state());
}
}
void AbsoluteHumidityComponent::dump_config() {
LOG_SENSOR("", "Absolute Humidity", this);
switch (this->equation_) {
case BUCK:
ESP_LOGCONFIG(TAG, "Saturation Vapor Pressure Equation: Buck");
break;
case TETENS:
ESP_LOGCONFIG(TAG, "Saturation Vapor Pressure Equation: Tetens");
break;
case WOBUS:
ESP_LOGCONFIG(TAG, "Saturation Vapor Pressure Equation: Wobus");
break;
default:
ESP_LOGE(TAG, "Invalid saturation vapor pressure equation selection!");
break;
}
ESP_LOGCONFIG(TAG, "Sources");
ESP_LOGCONFIG(TAG, " Temperature: '%s'", this->temperature_sensor_->get_name().c_str());
ESP_LOGCONFIG(TAG, " Relative Humidity: '%s'", this->humidity_sensor_->get_name().c_str());
}
float AbsoluteHumidityComponent::get_setup_priority() const { return setup_priority::DATA; }
void AbsoluteHumidityComponent::loop() {
if (!this->next_update_) {
return;
}
this->next_update_ = false;
// Ensure we have source data
const bool no_temperature = std::isnan(this->temperature_);
const bool no_humidity = std::isnan(this->humidity_);
if (no_temperature || no_humidity) {
if (no_temperature) {
ESP_LOGW(TAG, "No valid state from temperature sensor!");
}
if (no_humidity) {
ESP_LOGW(TAG, "No valid state from temperature sensor!");
}
ESP_LOGW(TAG, "Unable to calculate absolute humidity.");
this->publish_state(NAN);
this->status_set_warning();
return;
}
// Convert to desired units
const float temperature_c = this->temperature_;
const float temperature_k = temperature_c + 273.15;
const float hr = this->humidity_ / 100;
// Calculate saturation vapor pressure
float es;
switch (this->equation_) {
case BUCK:
es = es_buck(temperature_c);
break;
case TETENS:
es = es_tetens(temperature_c);
break;
case WOBUS:
es = es_wobus(temperature_c);
break;
default:
ESP_LOGE(TAG, "Invalid saturation vapor pressure equation selection!");
this->publish_state(NAN);
this->status_set_error();
return;
}
ESP_LOGD(TAG, "Saturation vapor pressure %f kPa", es);
// Calculate absolute humidity
const float absolute_humidity = vapor_density(es, hr, temperature_k);
// Publish absolute humidity
ESP_LOGD(TAG, "Publishing absolute humidity %f g/m³", absolute_humidity);
this->status_clear_warning();
this->publish_state(absolute_humidity);
}
// Buck equation (https://en.wikipedia.org/wiki/Arden_Buck_equation)
// More accurate than Tetens in normal meteorologic conditions
float AbsoluteHumidityComponent::es_buck(float temperature_c) {
float a, b, c, d;
if (temperature_c >= 0) {
a = 0.61121;
b = 18.678;
c = 234.5;
d = 257.14;
} else {
a = 0.61115;
b = 18.678;
c = 233.7;
d = 279.82;
}
return a * expf((b - (temperature_c / c)) * (temperature_c / (d + temperature_c)));
}
// Tetens equation (https://en.wikipedia.org/wiki/Tetens_equation)
float AbsoluteHumidityComponent::es_tetens(float temperature_c) {
float a, b;
if (temperature_c >= 0) {
a = 17.27;
b = 237.3;
} else {
a = 21.875;
b = 265.5;
}
return 0.61078 * expf((a * temperature_c) / (temperature_c + b));
}
// Wobus equation
// https://wahiduddin.net/calc/density_altitude.htm
// https://wahiduddin.net/calc/density_algorithms.htm
// Calculate the saturation vapor pressure (kPa)
float AbsoluteHumidityComponent::es_wobus(float t) {
// THIS FUNCTION RETURNS THE SATURATION VAPOR PRESSURE ESW (MILLIBARS)
// OVER LIQUID WATER GIVEN THE TEMPERATURE T (CELSIUS). THE POLYNOMIAL
// APPROXIMATION BELOW IS DUE TO HERMAN WOBUS, A MATHEMATICIAN WHO
// WORKED AT THE NAVY WEATHER RESEARCH FACILITY, NORFOLK, VIRGINIA,
// BUT WHO IS NOW RETIRED. THE COEFFICIENTS OF THE POLYNOMIAL WERE
// CHOSEN TO FIT THE VALUES IN TABLE 94 ON PP. 351-353 OF THE SMITH-
// SONIAN METEOROLOGICAL TABLES BY ROLAND LIST (6TH EDITION). THE
// APPROXIMATION IS VALID FOR -50 < T < 100C.
//
// Baker, Schlatter 17-MAY-1982 Original version.
const float c0 = +0.99999683e00;
const float c1 = -0.90826951e-02;
const float c2 = +0.78736169e-04;
const float c3 = -0.61117958e-06;
const float c4 = +0.43884187e-08;
const float c5 = -0.29883885e-10;
const float c6 = +0.21874425e-12;
const float c7 = -0.17892321e-14;
const float c8 = +0.11112018e-16;
const float c9 = -0.30994571e-19;
const float p = c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * (c6 + t * (c7 + t * (c8 + t * (c9)))))))));
return 0.61078 / pow(p, 8);
}
// From https://www.environmentalbiophysics.org/chalk-talk-how-to-calculate-absolute-humidity/
// H/T to https://esphome.io/cookbook/bme280_environment.html
// H/T to https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
float AbsoluteHumidityComponent::vapor_density(float es, float hr, float ta) {
// es = saturated vapor pressure (kPa)
// hr = relative humidity [0-1]
// ta = absolute temperature (K)
const float ea = hr * es * 1000; // vapor pressure of the air (Pa)
const float mw = 18.01528; // molar mass of water (g⋅mol⁻¹)
const float r = 8.31446261815324; // molar gas constant (J⋅K⁻¹)
return (ea * mw) / (r * ta);
}
} // namespace absolute_humidity
} // namespace esphome

View File

@@ -1,76 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
namespace esphome {
namespace absolute_humidity {
/// Enum listing all implemented saturation vapor pressure equations.
enum SaturationVaporPressureEquation {
BUCK,
TETENS,
WOBUS,
};
/// This class implements calculation of absolute humidity from temperature and relative humidity.
class AbsoluteHumidityComponent : public sensor::Sensor, public Component {
public:
AbsoluteHumidityComponent() = default;
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { this->temperature_sensor_ = temperature_sensor; }
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { this->humidity_sensor_ = humidity_sensor; }
void set_equation(SaturationVaporPressureEquation equation) { this->equation_ = equation; }
void setup() override;
void dump_config() override;
float get_setup_priority() const override;
void loop() override;
protected:
void temperature_callback_(float state) {
this->next_update_ = true;
this->temperature_ = state;
}
void humidity_callback_(float state) {
this->next_update_ = true;
this->humidity_ = state;
}
/** Buck equation for saturation vapor pressure in kPa.
*
* @param temperature_c Air temperature in °C.
*/
static float es_buck(float temperature_c);
/** Tetens equation for saturation vapor pressure in kPa.
*
* @param temperature_c Air temperature in °C.
*/
static float es_tetens(float temperature_c);
/** Wobus equation for saturation vapor pressure in kPa.
*
* @param temperature_c Air temperature in °C.
*/
static float es_wobus(float temperature_c);
/** Calculate vapor density (absolute humidity) in g/m³.
*
* @param es Saturation vapor pressure in kPa.
* @param hr Relative humidity 0 to 1.
* @param ta Absolute temperature in K.
* @param heater_duration The duration in ms that the heater should turn on for when measuring.
*/
static float vapor_density(float es, float hr, float ta);
sensor::Sensor *temperature_sensor_{nullptr};
sensor::Sensor *humidity_sensor_{nullptr};
bool next_update_{false};
float temperature_{NAN};
float humidity_{NAN};
SaturationVaporPressureEquation equation_;
};
} // namespace absolute_humidity
} // namespace esphome

View File

@@ -1,56 +0,0 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
from esphome.const import (
CONF_HUMIDITY,
CONF_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
CONF_EQUATION,
ICON_WATER,
UNIT_GRAMS_PER_CUBIC_METER,
)
absolute_humidity_ns = cg.esphome_ns.namespace("absolute_humidity")
AbsoluteHumidityComponent = absolute_humidity_ns.class_(
"AbsoluteHumidityComponent", sensor.Sensor, cg.Component
)
SaturationVaporPressureEquation = absolute_humidity_ns.enum(
"SaturationVaporPressureEquation"
)
EQUATION = {
"BUCK": SaturationVaporPressureEquation.BUCK,
"TETENS": SaturationVaporPressureEquation.TETENS,
"WOBUS": SaturationVaporPressureEquation.WOBUS,
}
CONFIG_SCHEMA = (
sensor.sensor_schema(
unit_of_measurement=UNIT_GRAMS_PER_CUBIC_METER,
icon=ICON_WATER,
accuracy_decimals=2,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(
{
cv.GenerateID(): cv.declare_id(AbsoluteHumidityComponent),
cv.Required(CONF_TEMPERATURE): cv.use_id(sensor.Sensor),
cv.Required(CONF_HUMIDITY): cv.use_id(sensor.Sensor),
cv.Optional(CONF_EQUATION, default="WOBUS"): cv.enum(EQUATION, upper=True),
}
)
.extend(cv.COMPONENT_SCHEMA)
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
temperature_sensor = await cg.get_variable(config[CONF_TEMPERATURE])
cg.add(var.set_temperature_sensor(temperature_sensor))
humidity_sensor = await cg.get_variable(config[CONF_HUMIDITY])
cg.add(var.set_humidity_sensor(humidity_sensor))
cg.add(var.set_equation(config[CONF_EQUATION]))

View File

@@ -121,8 +121,11 @@ void IRAM_ATTR HOT AcDimmerDataStore::gpio_intr() {
// calculate time until enable in µs: (1.0-value)*cycle_time, but with integer arithmetic // calculate time until enable in µs: (1.0-value)*cycle_time, but with integer arithmetic
// also take into account min_power // also take into account min_power
auto min_us = this->cycle_time_us * this->min_power / 1000; auto min_us = this->cycle_time_us * this->min_power / 1000;
this->enable_time_us = std::max((uint32_t) 1, ((65535 - this->value) * (this->cycle_time_us - min_us)) / 65535); // calculate required value to provide a true RMS voltage output
this->enable_time_us =
std::max((uint32_t) 1, (uint32_t)((65535 - (acos(1 - (2 * this->value / 65535.0)) / 3.14159 * 65535)) *
(this->cycle_time_us - min_us)) /
65535);
if (this->method == DIM_METHOD_LEADING_PULSE) { if (this->method == DIM_METHOD_LEADING_PULSE) {
// Minimum pulse time should be enough for the triac to trigger when it is close to the ZC zone // Minimum pulse time should be enough for the triac to trigger when it is close to the ZC zone
// this is for brightness near 99% // this is for brightness near 99%
@@ -203,7 +206,6 @@ void AcDimmer::setup() {
#endif #endif
} }
void AcDimmer::write_state(float state) { void AcDimmer::write_state(float state) {
state = std::acos(1 - (2 * state)) / 3.14159; // RMS power compensation
auto new_value = static_cast<uint16_t>(roundf(state * 65535)); auto new_value = static_cast<uint16_t>(roundf(state * 65535));
if (new_value != 0 && this->store_.value == 0) if (new_value != 0 && this->store_.value == 0)
this->store_.init_cycle = this->init_with_half_cycle_; this->store_.init_cycle = this->init_with_half_cycle_;

View File

@@ -11,38 +11,19 @@ ADC_MODE(ADC_VCC)
#endif #endif
#endif #endif
#ifdef USE_RP2040
#include <hardware/adc.h>
#endif
namespace esphome { namespace esphome {
namespace adc { namespace adc {
static const char *const TAG = "adc"; static const char *const TAG = "adc";
// 13 bits for S3 / 12 bit for all other esp32 variants
// 13bit for S2, and 12bit for all other esp32 variants // create a const to avoid the repated cast to enum
#ifdef USE_ESP32 #ifdef USE_ESP32
static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1); static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
#ifndef SOC_ADC_RTC_MAX_BITWIDTH
#if USE_ESP32_VARIANT_ESP32S2
static const int SOC_ADC_RTC_MAX_BITWIDTH = 13;
#else
static const int SOC_ADC_RTC_MAX_BITWIDTH = 12;
#endif
#endif #endif
static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1; // 4095 (12 bit) or 8191 (13 bit) void ADCSensor::setup() {
static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1; // 2048 (12 bit) or 4096 (13 bit)
#endif
#ifdef USE_RP2040
extern "C"
#endif
void
ADCSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str()); ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
#if !defined(USE_ADC_SENSOR_VCC) && !defined(USE_RP2040) #ifndef USE_ADC_SENSOR_VCC
pin_->setup(); pin_->setup();
#endif #endif
@@ -70,17 +51,11 @@ extern "C"
} }
} }
#endif // USE_ESP32 // adc_gpio_init doesn't exist on ESP32-S2, ESP32-C3 or ESP32-H2
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32H2) && !defined(USE_ESP32_VARIANT_ESP32S2)
#ifdef USE_RP2040 adc_gpio_init(ADC_UNIT_1, (adc_channel_t) channel_);
static bool initialized = false;
if (!initialized) {
adc_init();
initialized = true;
}
#endif #endif
#endif // USE_ESP32
ESP_LOGCONFIG(TAG, "ADC '%s' setup finished!", this->get_name().c_str());
} }
void ADCSensor::dump_config() { void ADCSensor::dump_config() {
@@ -100,29 +75,22 @@ void ADCSensor::dump_config() {
} else { } else {
switch (this->attenuation_) { switch (this->attenuation_) {
case ADC_ATTEN_DB_0: case ADC_ATTEN_DB_0:
ESP_LOGCONFIG(TAG, " Attenuation: 0db"); ESP_LOGCONFIG(TAG, " Attenuation: 0db (max 1.1V)");
break; break;
case ADC_ATTEN_DB_2_5: case ADC_ATTEN_DB_2_5:
ESP_LOGCONFIG(TAG, " Attenuation: 2.5db"); ESP_LOGCONFIG(TAG, " Attenuation: 2.5db (max 1.5V)");
break; break;
case ADC_ATTEN_DB_6: case ADC_ATTEN_DB_6:
ESP_LOGCONFIG(TAG, " Attenuation: 6db"); ESP_LOGCONFIG(TAG, " Attenuation: 6db (max 2.2V)");
break; break;
case ADC_ATTEN_DB_11: case ADC_ATTEN_DB_11:
ESP_LOGCONFIG(TAG, " Attenuation: 11db"); ESP_LOGCONFIG(TAG, " Attenuation: 11db (max 3.9V)");
break; break;
default: // This is to satisfy the unused ADC_ATTEN_MAX default: // This is to satisfy the unused ADC_ATTEN_MAX
break; break;
} }
} }
#endif // USE_ESP32 #endif // USE_ESP32
#ifdef USE_RP2040
if (this->is_temperature_) {
ESP_LOGCONFIG(TAG, " Pin: Temperature");
} else {
LOG_PIN(" Pin: ", pin_);
}
#endif
LOG_UPDATE_INTERVAL(this); LOG_UPDATE_INTERVAL(this);
} }
@@ -161,16 +129,16 @@ float ADCSensor::sample() {
return mv / 1000.0f; return mv / 1000.0f;
} }
int raw11, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX; int raw11, raw6 = 4095, raw2 = 4095, raw0 = 4095;
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_11); adc1_config_channel_atten(channel_, ADC_ATTEN_DB_11);
raw11 = adc1_get_raw(channel_); raw11 = adc1_get_raw(channel_);
if (raw11 < ADC_MAX) { if (raw11 < 4095) {
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_6); adc1_config_channel_atten(channel_, ADC_ATTEN_DB_6);
raw6 = adc1_get_raw(channel_); raw6 = adc1_get_raw(channel_);
if (raw6 < ADC_MAX) { if (raw6 < 4095) {
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_2_5); adc1_config_channel_atten(channel_, ADC_ATTEN_DB_2_5);
raw2 = adc1_get_raw(channel_); raw2 = adc1_get_raw(channel_);
if (raw2 < ADC_MAX) { if (raw2 < 4095) {
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_0); adc1_config_channel_atten(channel_, ADC_ATTEN_DB_0);
raw0 = adc1_get_raw(channel_); raw0 = adc1_get_raw(channel_);
} }
@@ -186,43 +154,20 @@ float ADCSensor::sample() {
uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &cal_characteristics_[(int) ADC_ATTEN_DB_2_5]); uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &cal_characteristics_[(int) ADC_ATTEN_DB_2_5]);
uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &cal_characteristics_[(int) ADC_ATTEN_DB_0]); uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &cal_characteristics_[(int) ADC_ATTEN_DB_0]);
// Contribution of each value, in range 0-2048 (12 bit ADC) or 0-4096 (13 bit ADC) // Contribution of each value, in range 0-2048
uint32_t c11 = std::min(raw11, ADC_HALF); uint32_t c11 = std::min(raw11, 2048);
uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF); uint32_t c6 = 2048 - std::abs(raw6 - 2048);
uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF); uint32_t c2 = 2048 - std::abs(raw2 - 2048);
uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF); uint32_t c0 = std::min(4095 - raw0, 2048);
// max theoretical csum value is 4096*4 = 16384 // max theoretical csum value is 2048*4 = 8192
uint32_t csum = c11 + c6 + c2 + c0; uint32_t csum = c11 + c6 + c2 + c0;
// each mv is max 3900; so max value is 3900*4096*4, fits in unsigned32 // each mv is max 3900; so max value is 3900*2048*4, fits in unsigned
uint32_t mv_scaled = (mv11 * c11) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0); uint32_t mv_scaled = (mv11 * c11) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
return mv_scaled / (float) (csum * 1000U); return mv_scaled / (float) (csum * 1000U);
} }
#endif // USE_ESP32 #endif // USE_ESP32
#ifdef USE_RP2040
float ADCSensor::sample() {
if (this->is_temperature_) {
adc_set_temp_sensor_enabled(true);
delay(1);
adc_select_input(4);
} else {
uint8_t pin = this->pin_->get_pin();
adc_gpio_init(pin);
adc_select_input(pin - 26);
}
int raw = adc_read();
if (this->is_temperature_) {
adc_set_temp_sensor_enabled(false);
}
if (output_raw_) {
return raw;
}
return raw * 3.3f / 4096.0f;
}
#endif
#ifdef USE_ESP8266 #ifdef USE_ESP8266
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; } std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
#endif #endif

View File

@@ -38,18 +38,10 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
std::string unique_id() override; std::string unique_id() override;
#endif #endif
#ifdef USE_RP2040
void set_is_temperature() { is_temperature_ = true; }
#endif
protected: protected:
InternalGPIOPin *pin_; InternalGPIOPin *pin_;
bool output_raw_{false}; bool output_raw_{false};
#ifdef USE_RP2040
bool is_temperature_{false};
#endif
#ifdef USE_ESP32 #ifdef USE_ESP32
adc_atten_t attenuation_{ADC_ATTEN_DB_0}; adc_atten_t attenuation_{ADC_ATTEN_DB_0};
adc1_channel_t channel_{}; adc1_channel_t channel_{};

View File

@@ -94,9 +94,6 @@ def validate_adc_pin(value):
if str(value).upper() == "VCC": if str(value).upper() == "VCC":
return cv.only_on_esp8266("VCC") return cv.only_on_esp8266("VCC")
if str(value).upper() == "TEMPERATURE":
return cv.only_on_rp2040("TEMPERATURE")
if CORE.is_esp32: if CORE.is_esp32:
value = pins.internal_gpio_input_pin_number(value) value = pins.internal_gpio_input_pin_number(value)
variant = get_esp32_variant() variant = get_esp32_variant()
@@ -120,12 +117,6 @@ def validate_adc_pin(value):
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True {CONF_ANALOG: True, CONF_INPUT: True}, internal=True
)(value) )(value)
if CORE.is_rp2040:
value = pins.internal_gpio_input_pin_number(value)
if value not in (26, 27, 28, 29):
raise cv.Invalid("RP2040: Only pins 26, 27, 28 and 29 support ADC.")
return pins.internal_gpio_input_pin_schema(value)
raise NotImplementedError raise NotImplementedError
@@ -169,8 +160,6 @@ async def to_code(config):
if config[CONF_PIN] == "VCC": if config[CONF_PIN] == "VCC":
cg.add_define("USE_ADC_SENSOR_VCC") cg.add_define("USE_ADC_SENSOR_VCC")
elif config[CONF_PIN] == "TEMPERATURE":
cg.add(var.set_is_temperature())
else: else:
pin = await cg.gpio_pin_expression(config[CONF_PIN]) pin = await cg.gpio_pin_expression(config[CONF_PIN])
cg.add(var.set_pin(pin)) cg.add(var.set_pin(pin))

View File

@@ -1,23 +0,0 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import spi
from esphome.const import CONF_ID
DEPENDENCIES = ["spi"]
MULTI_CONF = True
CODEOWNERS = ["@DeerMaximum"]
adc128s102_ns = cg.esphome_ns.namespace("adc128s102")
ADC128S102 = adc128s102_ns.class_("ADC128S102", cg.Component, spi.SPIDevice)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(ADC128S102),
}
).extend(spi.spi_device_schema(cs_pin_required=True))
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await spi.register_spi_device(var, config)

View File

@@ -1,35 +0,0 @@
#include "adc128s102.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc128s102 {
static const char *const TAG = "adc128s102";
float ADC128S102::get_setup_priority() const { return setup_priority::HARDWARE; }
void ADC128S102::setup() {
ESP_LOGCONFIG(TAG, "Setting up adc128s102");
this->spi_setup();
}
void ADC128S102::dump_config() {
ESP_LOGCONFIG(TAG, "ADC128S102:");
LOG_PIN(" CS Pin:", this->cs_);
}
uint16_t ADC128S102::read_data(uint8_t channel) {
uint8_t control = channel << 3;
this->enable();
uint8_t adc_primary_byte = this->transfer_byte(control);
uint8_t adc_secondary_byte = this->transfer_byte(0x00);
this->disable();
uint16_t digital_value = adc_primary_byte << 8 | adc_secondary_byte;
return digital_value;
}
} // namespace adc128s102
} // namespace esphome

View File

@@ -1,23 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/components/spi/spi.h"
namespace esphome {
namespace adc128s102 {
class ADC128S102 : public Component,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
spi::DATA_RATE_10MHZ> {
public:
ADC128S102() = default;
void setup() override;
void dump_config() override;
float get_setup_priority() const override;
uint16_t read_data(uint8_t channel);
};
} // namespace adc128s102
} // namespace esphome

View File

@@ -1,38 +0,0 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, voltage_sampler
from esphome.const import CONF_ID, CONF_CHANNEL
from .. import adc128s102_ns, ADC128S102
AUTO_LOAD = ["voltage_sampler"]
DEPENDENCIES = ["adc128s102"]
ADC128S102Sensor = adc128s102_ns.class_(
"ADC128S102Sensor",
sensor.Sensor,
cg.PollingComponent,
voltage_sampler.VoltageSampler,
)
CONF_ADC128S102_ID = "adc128s102_id"
CONFIG_SCHEMA = (
sensor.sensor_schema(ADC128S102Sensor)
.extend(
{
cv.GenerateID(CONF_ADC128S102_ID): cv.use_id(ADC128S102),
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=7),
}
)
.extend(cv.polling_component_schema("60s"))
)
async def to_code(config):
var = cg.new_Pvariable(
config[CONF_ID],
config[CONF_CHANNEL],
)
await cg.register_parented(var, config[CONF_ADC128S102_ID])
await cg.register_component(var, config)
await sensor.register_sensor(var, config)

View File

@@ -1,24 +0,0 @@
#include "adc128s102_sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace adc128s102 {
static const char *const TAG = "adc128s102.sensor";
ADC128S102Sensor::ADC128S102Sensor(uint8_t channel) : channel_(channel) {}
float ADC128S102Sensor::get_setup_priority() const { return setup_priority::DATA; }
void ADC128S102Sensor::dump_config() {
LOG_SENSOR("", "ADC128S102 Sensor", this);
ESP_LOGCONFIG(TAG, " Pin: %u", this->channel_);
LOG_UPDATE_INTERVAL(this);
}
float ADC128S102Sensor::sample() { return this->parent_->read_data(this->channel_); }
void ADC128S102Sensor::update() { this->publish_state(this->sample()); }
} // namespace adc128s102
} // namespace esphome

View File

@@ -1,29 +0,0 @@
#pragma once
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/voltage_sampler/voltage_sampler.h"
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "../adc128s102.h"
namespace esphome {
namespace adc128s102 {
class ADC128S102Sensor : public PollingComponent,
public Parented<ADC128S102>,
public sensor::Sensor,
public voltage_sampler::VoltageSampler {
public:
ADC128S102Sensor(uint8_t channel);
void update() override;
void dump_config() override;
float get_setup_priority() const override;
float sample() override;
protected:
uint8_t channel_;
};
} // namespace adc128s102
} // namespace esphome

View File

@@ -5,8 +5,6 @@
#include "esphome/components/display/display_buffer.h" #include "esphome/components/display/display_buffer.h"
#include "esphome/components/light/addressable_light.h" #include "esphome/components/light/addressable_light.h"
#include <vector>
namespace esphome { namespace esphome {
namespace addressable_light { namespace addressable_light {
@@ -42,8 +40,6 @@ class AddressableLightDisplay : public display::DisplayBuffer, public PollingCom
void setup() override; void setup() override;
void display(); void display();
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
protected: protected:
int get_width_internal() override; int get_width_internal() override;
int get_height_internal() override; int get_height_internal() override;

View File

@@ -5,8 +5,6 @@
#include "esphome/components/i2c/i2c.h" #include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#include <vector>
namespace esphome { namespace esphome {
namespace ade7953 { namespace ade7953 {
@@ -84,7 +82,7 @@ class ADE7953 : public i2c::I2CDevice, public PollingComponent {
return i2c::ERROR_OK; return i2c::ERROR_OK;
} }
InternalGPIOPin *irq_pin_{nullptr}; InternalGPIOPin *irq_pin_ = nullptr;
bool is_setup_{false}; bool is_setup_{false};
sensor::Sensor *voltage_sensor_{nullptr}; sensor::Sensor *voltage_sensor_{nullptr};
sensor::Sensor *current_a_sensor_{nullptr}; sensor::Sensor *current_a_sensor_{nullptr};

View File

@@ -9,7 +9,7 @@ static const char *const TAG = "ads1115";
static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00; static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00;
static const uint8_t ADS1115_REGISTER_CONFIG = 0x01; static const uint8_t ADS1115_REGISTER_CONFIG = 0x01;
static const uint8_t ADS1115_DATA_RATE_860_SPS = 0b111; // 3300_SPS for ADS1015 static const uint8_t ADS1115_DATA_RATE_860_SPS = 0b111;
void ADS1115Component::setup() { void ADS1115Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADS1115..."); ESP_LOGCONFIG(TAG, "Setting up ADS1115...");
@@ -18,9 +18,6 @@ void ADS1115Component::setup() {
this->mark_failed(); this->mark_failed();
return; return;
} }
ESP_LOGCONFIG(TAG, "Configuring ADS1115...");
uint16_t config = 0; uint16_t config = 0;
// Clear single-shot bit // Clear single-shot bit
// 0b0xxxxxxxxxxxxxxx // 0b0xxxxxxxxxxxxxxx
@@ -80,7 +77,6 @@ void ADS1115Component::dump_config() {
LOG_SENSOR(" ", "Sensor", sensor); LOG_SENSOR(" ", "Sensor", sensor);
ESP_LOGCONFIG(TAG, " Multiplexer: %u", sensor->get_multiplexer()); ESP_LOGCONFIG(TAG, " Multiplexer: %u", sensor->get_multiplexer());
ESP_LOGCONFIG(TAG, " Gain: %u", sensor->get_gain()); ESP_LOGCONFIG(TAG, " Gain: %u", sensor->get_gain());
ESP_LOGCONFIG(TAG, " Resolution: %u", sensor->get_resolution());
} }
} }
float ADS1115Component::request_measurement(ADS1115Sensor *sensor) { float ADS1115Component::request_measurement(ADS1115Sensor *sensor) {
@@ -131,45 +127,27 @@ float ADS1115Component::request_measurement(ADS1115Sensor *sensor) {
this->status_set_warning(); this->status_set_warning();
return NAN; return NAN;
} }
if (sensor->get_resolution() == ADS1015_12_BITS) {
bool negative = (raw_conversion >> 15) == 1;
// shift raw_conversion as it's only 12-bits, left justified
raw_conversion = raw_conversion >> (16 - ADS1015_12_BITS);
// check if number was negative in order to keep the sign
if (negative) {
// the number was negative
// 1) set the negative bit back
raw_conversion |= 0x8000;
// 2) reset the former (shifted) negative bit
raw_conversion &= 0xF7FF;
}
}
auto signed_conversion = static_cast<int16_t>(raw_conversion); auto signed_conversion = static_cast<int16_t>(raw_conversion);
float millivolts; float millivolts;
float divider = (sensor->get_resolution() == ADS1115_16_BITS) ? 32768.0f : 2048.0f;
switch (sensor->get_gain()) { switch (sensor->get_gain()) {
case ADS1115_GAIN_6P144: case ADS1115_GAIN_6P144:
millivolts = (signed_conversion * 6144) / divider; millivolts = signed_conversion * 0.187500f;
break; break;
case ADS1115_GAIN_4P096: case ADS1115_GAIN_4P096:
millivolts = (signed_conversion * 4096) / divider; millivolts = signed_conversion * 0.125000f;
break; break;
case ADS1115_GAIN_2P048: case ADS1115_GAIN_2P048:
millivolts = (signed_conversion * 2048) / divider; millivolts = signed_conversion * 0.062500f;
break; break;
case ADS1115_GAIN_1P024: case ADS1115_GAIN_1P024:
millivolts = (signed_conversion * 1024) / divider; millivolts = signed_conversion * 0.031250f;
break; break;
case ADS1115_GAIN_0P512: case ADS1115_GAIN_0P512:
millivolts = (signed_conversion * 512) / divider; millivolts = signed_conversion * 0.015625f;
break; break;
case ADS1115_GAIN_0P256: case ADS1115_GAIN_0P256:
millivolts = (signed_conversion * 256) / divider; millivolts = signed_conversion * 0.007813f;
break; break;
default: default:
millivolts = NAN; millivolts = NAN;

View File

@@ -5,8 +5,6 @@
#include "esphome/components/i2c/i2c.h" #include "esphome/components/i2c/i2c.h"
#include "esphome/components/voltage_sampler/voltage_sampler.h" #include "esphome/components/voltage_sampler/voltage_sampler.h"
#include <vector>
namespace esphome { namespace esphome {
namespace ads1115 { namespace ads1115 {
@@ -30,11 +28,6 @@ enum ADS1115Gain {
ADS1115_GAIN_0P256 = 0b101, ADS1115_GAIN_0P256 = 0b101,
}; };
enum ADS1115Resolution {
ADS1115_16_BITS = 16,
ADS1015_12_BITS = 12,
};
class ADS1115Sensor; class ADS1115Sensor;
class ADS1115Component : public Component, public i2c::I2CDevice { class ADS1115Component : public Component, public i2c::I2CDevice {
@@ -63,17 +56,15 @@ class ADS1115Sensor : public sensor::Sensor, public PollingComponent, public vol
void update() override; void update() override;
void set_multiplexer(ADS1115Multiplexer multiplexer) { multiplexer_ = multiplexer; } void set_multiplexer(ADS1115Multiplexer multiplexer) { multiplexer_ = multiplexer; }
void set_gain(ADS1115Gain gain) { gain_ = gain; } void set_gain(ADS1115Gain gain) { gain_ = gain; }
void set_resolution(ADS1115Resolution resolution) { resolution_ = resolution; }
float sample() override; float sample() override;
uint8_t get_multiplexer() const { return multiplexer_; } uint8_t get_multiplexer() const { return multiplexer_; }
uint8_t get_gain() const { return gain_; } uint8_t get_gain() const { return gain_; }
uint8_t get_resolution() const { return resolution_; }
protected: protected:
ADS1115Component *parent_; ADS1115Component *parent_;
ADS1115Multiplexer multiplexer_; ADS1115Multiplexer multiplexer_;
ADS1115Gain gain_; ADS1115Gain gain_;
ADS1115Resolution resolution_;
}; };
} // namespace ads1115 } // namespace ads1115

View File

@@ -4,7 +4,6 @@ from esphome.components import sensor, voltage_sampler
from esphome.const import ( from esphome.const import (
CONF_GAIN, CONF_GAIN,
CONF_MULTIPLEXER, CONF_MULTIPLEXER,
CONF_RESOLUTION,
DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT, STATE_CLASS_MEASUREMENT,
UNIT_VOLT, UNIT_VOLT,
@@ -36,12 +35,6 @@ GAIN = {
"0.256": ADS1115Gain.ADS1115_GAIN_0P256, "0.256": ADS1115Gain.ADS1115_GAIN_0P256,
} }
ADS1115Resolution = ads1115_ns.enum("ADS1115Resolution")
RESOLUTION = {
"16_BITS": ADS1115Resolution.ADS1115_16_BITS,
"12_BITS": ADS1115Resolution.ADS1015_12_BITS,
}
def validate_gain(value): def validate_gain(value):
if isinstance(value, float): if isinstance(value, float):
@@ -70,9 +63,6 @@ CONFIG_SCHEMA = (
cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component), cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component),
cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"), cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"),
cv.Required(CONF_GAIN): validate_gain, cv.Required(CONF_GAIN): validate_gain,
cv.Optional(CONF_RESOLUTION, default="16_BITS"): cv.enum(
RESOLUTION, upper=True, space="_"
),
} }
) )
.extend(cv.polling_component_schema("60s")) .extend(cv.polling_component_schema("60s"))
@@ -87,6 +77,5 @@ async def to_code(config):
cg.add(var.set_multiplexer(config[CONF_MULTIPLEXER])) cg.add(var.set_multiplexer(config[CONF_MULTIPLEXER]))
cg.add(var.set_gain(config[CONF_GAIN])) cg.add(var.set_gain(config[CONF_GAIN]))
cg.add(var.set_resolution(config[CONF_RESOLUTION]))
cg.add(paren.register_sensor(var)) cg.add(paren.register_sensor(var))

View File

@@ -122,9 +122,8 @@ void AHT10Component::update() {
this->temperature_sensor_->publish_state(temperature); this->temperature_sensor_->publish_state(temperature);
} }
if (this->humidity_sensor_ != nullptr) { if (this->humidity_sensor_ != nullptr) {
if (std::isnan(humidity)) { if (std::isnan(humidity))
ESP_LOGW(TAG, "Invalid humidity! Sensor reported 0%% Hum"); ESP_LOGW(TAG, "Invalid humidity! Sensor reported 0%% Hum");
}
this->humidity_sensor_->publish_state(humidity); this->humidity_sensor_->publish_state(humidity);
} }
this->status_clear_warning(); this->status_clear_warning();

View File

@@ -18,8 +18,8 @@ class AHT10Component : public PollingComponent, public i2c::I2CDevice {
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { humidity_sensor_ = humidity_sensor; } void set_humidity_sensor(sensor::Sensor *humidity_sensor) { humidity_sensor_ = humidity_sensor; }
protected: protected:
sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *temperature_sensor_;
sensor::Sensor *humidity_sensor_{nullptr}; sensor::Sensor *humidity_sensor_;
}; };
} // namespace aht10 } // namespace aht10

View File

@@ -38,7 +38,7 @@ void AirthingsWaveMini::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
} }
case ESP_GATTC_READ_CHAR_EVT: { case ESP_GATTC_READ_CHAR_EVT: {
if (param->read.conn_id != this->parent()->get_conn_id()) if (param->read.conn_id != this->parent()->conn_id)
break; break;
if (param->read.status != ESP_GATT_OK) { if (param->read.status != ESP_GATT_OK) {
ESP_LOGW(TAG, "Error reading char at handle %d, status=%d", param->read.handle, param->read.status); ESP_LOGW(TAG, "Error reading char at handle %d, status=%d", param->read.handle, param->read.status);
@@ -88,8 +88,8 @@ void AirthingsWaveMini::update() {
} }
void AirthingsWaveMini::request_read_values_() { void AirthingsWaveMini::request_read_values_() {
auto status = esp_ble_gattc_read_char(this->parent()->get_gattc_if(), this->parent()->get_conn_id(), this->handle_, auto status =
ESP_GATT_AUTH_REQ_NONE); esp_ble_gattc_read_char(this->parent()->gattc_if, this->parent()->conn_id, this->handle_, ESP_GATT_AUTH_REQ_NONE);
if (status) { if (status) {
ESP_LOGW(TAG, "Error sending read request for sensor, status=%d", status); ESP_LOGW(TAG, "Error sending read request for sensor, status=%d", status);
} }

View File

@@ -38,7 +38,7 @@ void AirthingsWavePlus::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
} }
case ESP_GATTC_READ_CHAR_EVT: { case ESP_GATTC_READ_CHAR_EVT: {
if (param->read.conn_id != this->parent()->get_conn_id()) if (param->read.conn_id != this->parent()->conn_id)
break; break;
if (param->read.status != ESP_GATT_OK) { if (param->read.status != ESP_GATT_OK) {
ESP_LOGW(TAG, "Error reading char at handle %d, status=%d", param->read.handle, param->read.status); ESP_LOGW(TAG, "Error reading char at handle %d, status=%d", param->read.handle, param->read.status);
@@ -109,8 +109,8 @@ void AirthingsWavePlus::update() {
} }
void AirthingsWavePlus::request_read_values_() { void AirthingsWavePlus::request_read_values_() {
auto status = esp_ble_gattc_read_char(this->parent()->get_gattc_if(), this->parent()->get_conn_id(), this->handle_, auto status =
ESP_GATT_AUTH_REQ_NONE); esp_ble_gattc_read_char(this->parent()->gattc_if, this->parent()->conn_id, this->handle_, ESP_GATT_AUTH_REQ_NONE);
if (status) { if (status) {
ESP_LOGW(TAG, "Error sending read request for sensor, status=%d", status); ESP_LOGW(TAG, "Error sending read request for sensor, status=%d", status);
} }

View File

@@ -4,15 +4,33 @@
// - Arduino - AM2320: https://github.com/EngDial/AM2320/blob/master/src/AM2320.cpp // - Arduino - AM2320: https://github.com/EngDial/AM2320/blob/master/src/AM2320.cpp
#include "am2320.h" #include "am2320.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/hal.h"
namespace esphome { namespace esphome {
namespace am2320 { namespace am2320 {
static const char *const TAG = "am2320"; static const char *const TAG = "am2320";
// ---=== Calc CRC16 ===---
uint16_t crc_16(uint8_t *ptr, uint8_t length) {
uint16_t crc = 0xFFFF;
uint8_t i;
//------------------------------
while (length--) {
crc ^= *ptr++;
for (i = 0; i < 8; i++) {
if ((crc & 0x01) != 0) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
void AM2320Component::update() { void AM2320Component::update() {
uint8_t data[8]; uint8_t data[8];
data[0] = 0; data[0] = 0;
@@ -80,7 +98,7 @@ bool AM2320Component::read_data_(uint8_t *data) {
checksum = data[7] << 8; checksum = data[7] << 8;
checksum += data[6]; checksum += data[6];
if (crc16(data, 6) != checksum) { if (crc_16(data, 6) != checksum) {
ESP_LOGW(TAG, "AM2320 Checksum invalid!"); ESP_LOGW(TAG, "AM2320 Checksum invalid!");
return false; return false;
} }

View File

@@ -21,8 +21,8 @@ class AM2320Component : public PollingComponent, public i2c::I2CDevice {
bool read_data_(uint8_t *data); bool read_data_(uint8_t *data);
bool read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion = 0); bool read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion = 0);
sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *temperature_sensor_;
sensor::Sensor *humidity_sensor_{nullptr}; sensor::Sensor *humidity_sensor_;
}; };
} // namespace am2320 } // namespace am2320

View File

@@ -76,9 +76,9 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
if (this->current_sensor_ > 0) { if (this->current_sensor_ > 0) {
if (this->illuminance_ != nullptr) { 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_->get_gattc_if(), this->parent_->get_conn_id(), auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
this->char_handle_, packet->length, packet->data, packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); 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(), ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
status); status);
@@ -102,11 +102,10 @@ void Am43::update() {
if (this->battery_ != nullptr) { if (this->battery_ != nullptr) {
auto *packet = this->encoder_->get_battery_level_request(); auto *packet = this->encoder_->get_battery_level_request();
auto status = auto status =
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); 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); ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
}
} }
this->current_sensor_++; this->current_sensor_++;
} }

View File

@@ -27,8 +27,8 @@ void Am43Component::loop() {
if (this->node_state == espbt::ClientState::ESTABLISHED && !this->logged_in_) { 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 = auto status =
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); 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()); 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); ESP_LOGW(TAG, "[%s] Error writing set_pin to device, error = %d", this->get_name().c_str(), status);
@@ -54,11 +54,10 @@ void Am43Component::control(const CoverCall &call) {
if (call.get_stop()) { if (call.get_stop()) {
auto *packet = this->encoder_->get_stop_request(); auto *packet = this->encoder_->get_stop_request();
auto status = auto status =
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) { if (status)
ESP_LOGW(TAG, "[%s] Error writing stop command to device, error = %d", this->get_name().c_str(), status); ESP_LOGW(TAG, "[%s] Error writing stop command to device, error = %d", this->get_name().c_str(), status);
}
} }
if (call.get_position().has_value()) { if (call.get_position().has_value()) {
auto pos = *call.get_position(); auto pos = *call.get_position();
@@ -67,11 +66,10 @@ void Am43Component::control(const CoverCall &call) {
pos = 1 - pos; 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 = auto status =
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) { if (status)
ESP_LOGW(TAG, "[%s] Error writing set_position command to device, error = %d", this->get_name().c_str(), status); ESP_LOGW(TAG, "[%s] Error writing set_position command to device, error = %d", this->get_name().c_str(), status);
}
} }
} }
@@ -94,8 +92,7 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
} }
this->char_handle_ = chr->handle; this->char_handle_ = chr->handle;
auto status = esp_ble_gattc_register_for_notify(this->parent_->get_gattc_if(), this->parent_->get_remote_bda(), auto status = esp_ble_gattc_register_for_notify(this->parent_->gattc_if, this->parent_->remote_bda, chr->handle);
chr->handle);
if (status) { if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status); ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status);
} }
@@ -125,24 +122,21 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (this->decoder_->pin_ok_) { if (this->decoder_->pin_ok_) {
ESP_LOGI(TAG, "[%s] AM43 pin accepted.", this->get_name().c_str()); 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_->get_gattc_if(), this->parent_->get_conn_id(), auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
this->char_handle_, packet->length, packet->data, packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); ESP_GATT_AUTH_REQ_NONE);
if (status) { if (status)
ESP_LOGW(TAG, "[%s] Error writing set_position to device, error = %d", this->get_name().c_str(), status); ESP_LOGW(TAG, "[%s] Error writing set_position to device, error = %d", this->get_name().c_str(), status);
}
} else { } else {
ESP_LOGW(TAG, "[%s] AM43 pin rejected!", this->get_name().c_str()); ESP_LOGW(TAG, "[%s] AM43 pin rejected!", this->get_name().c_str());
} }
} }
if (this->decoder_->has_set_position_response() && !this->decoder_->set_position_ok_) { if (this->decoder_->has_set_position_response() && !this->decoder_->set_position_ok_)
ESP_LOGW(TAG, "[%s] Got nack after sending set_position. Bad pin?", this->get_name().c_str()); ESP_LOGW(TAG, "[%s] Got nack after sending set_position. Bad pin?", this->get_name().c_str());
}
if (this->decoder_->has_set_state_response() && !this->decoder_->set_state_ok_) { if (this->decoder_->has_set_state_response() && !this->decoder_->set_state_ok_)
ESP_LOGW(TAG, "[%s] Got nack after sending set_state. Bad pin?", this->get_name().c_str()); ESP_LOGW(TAG, "[%s] Got nack after sending set_state. Bad pin?", this->get_name().c_str());
}
break; break;
} }
default: default:

View File

@@ -15,24 +15,18 @@ AnalogThresholdBinarySensor = analog_threshold_ns.class_(
CONF_UPPER = "upper" CONF_UPPER = "upper"
CONF_LOWER = "lower" CONF_LOWER = "lower"
CONFIG_SCHEMA = ( CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
binary_sensor.binary_sensor_schema(AnalogThresholdBinarySensor) {
.extend( cv.GenerateID(): cv.declare_id(AnalogThresholdBinarySensor),
{ cv.Required(CONF_SENSOR_ID): cv.use_id(sensor.Sensor),
cv.Required(CONF_SENSOR_ID): cv.use_id(sensor.Sensor), cv.Required(CONF_THRESHOLD): cv.Any(
cv.Required(CONF_THRESHOLD): cv.Any( cv.float_,
cv.float_, cv.Schema(
cv.Schema( {cv.Required(CONF_UPPER): cv.float_, cv.Required(CONF_LOWER): cv.float_}
{
cv.Required(CONF_UPPER): cv.float_,
cv.Required(CONF_LOWER): cv.float_,
}
),
), ),
} ),
) }
.extend(cv.COMPONENT_SCHEMA) ).extend(cv.COMPONENT_SCHEMA)
)
async def to_code(config): async def to_code(config):

View File

@@ -13,7 +13,7 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ["display"] DEPENDENCIES = ["display"]
MULTI_CONF = True MULTI_CONF = True
Animation_ = display.display_ns.class_("Animation", espImage.Image_) Animation_ = display.display_ns.class_("Animation")
ANIMATION_SCHEMA = cv.Schema( ANIMATION_SCHEMA = cv.Schema(
{ {
@@ -76,8 +76,6 @@ async def to_code(config):
pos = 0 pos = 0
for frameIndex in range(frames): for frameIndex in range(frames):
image.seek(frameIndex) image.seek(frameIndex)
if CONF_RESIZE in config:
image.thumbnail(config[CONF_RESIZE])
frame = image.convert("RGB") frame = image.convert("RGB")
if CONF_RESIZE in config: if CONF_RESIZE in config:
frame = frame.resize([width, height]) frame = frame.resize([width, height])
@@ -117,7 +115,7 @@ async def to_code(config):
data[pos] = rgb & 255 data[pos] = rgb & 255
pos += 1 pos += 1
elif config[CONF_TYPE] in ["BINARY", "TRANSPARENT_BINARY"]: elif config[CONF_TYPE] == "BINARY":
width8 = ((width + 7) // 8) * 8 width8 = ((width + 7) // 8) * 8
data = [0 for _ in range((height * width8 // 8) * frames)] data = [0 for _ in range((height * width8 // 8) * frames)]
for frameIndex in range(frames): for frameIndex in range(frames):

View File

@@ -34,21 +34,17 @@ void Anova::control(const ClimateCall &call) {
ESP_LOGW(TAG, "Unsupported mode: %d", mode); ESP_LOGW(TAG, "Unsupported mode: %d", mode);
return; return;
} }
auto status = auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
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); 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()) { 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 = auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
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); ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
}
} }
} }
@@ -69,8 +65,7 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
} }
this->char_handle_ = chr->handle; this->char_handle_ = chr->handle;
auto status = esp_ble_gattc_register_for_notify(this->parent_->get_gattc_if(), this->parent_->get_remote_bda(), auto status = esp_ble_gattc_register_for_notify(this->parent_->gattc_if, this->parent_->remote_bda, chr->handle);
chr->handle);
if (status) { if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status); ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status);
} }
@@ -97,7 +92,7 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
} }
if (this->codec_->has_unit()) { if (this->codec_->has_unit()) {
this->fahrenheit_ = (this->codec_->unit_ == 'f'); this->fahrenheit_ = (this->codec_->unit_ == 'f');
ESP_LOGD(TAG, "Anova units is %s", this->fahrenheit_ ? "fahrenheit" : "celsius"); ESP_LOGD(TAG, "Anova units is %s", this->fahrenheit_ ? "fahrenheit" : "celcius");
this->current_request_++; this->current_request_++;
} }
this->publish_state(); this->publish_state();
@@ -117,8 +112,8 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
} }
if (pkt != nullptr) { if (pkt != nullptr) {
auto status = auto status =
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, pkt->length,
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); 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(), ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
status); status);
@@ -142,12 +137,10 @@ void Anova::update() {
auto *pkt = this->codec_->get_read_device_status_request(); auto *pkt = this->codec_->get_read_device_status_request();
if (this->current_request_ == 0) if (this->current_request_ == 0)
this->codec_->get_set_unit_request(this->fahrenheit_ ? 'f' : 'c'); this->codec_->get_set_unit_request(this->fahrenheit_ ? 'f' : 'c');
auto status = auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_, pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
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); ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
}
this->current_request_++; this->current_request_++;
} }
} }

View File

@@ -8,27 +8,6 @@ AUTO_LOAD = ["sensor", "binary_sensor"]
MULTI_CONF = True MULTI_CONF = True
CONF_APDS9960_ID = "apds9960_id" CONF_APDS9960_ID = "apds9960_id"
CONF_LED_DRIVE = "led_drive"
CONF_PROXIMITY_GAIN = "proximity_gain"
CONF_AMBIENT_LIGHT_GAIN = "ambient_light_gain"
CONF_GESTURE_LED_DRIVE = "gesture_led_drive"
CONF_GESTURE_GAIN = "gesture_gain"
CONF_GESTURE_WAIT_TIME = "gesture_wait_time"
DRIVE_LEVELS = {"100ma": 0, "50ma": 1, "25ma": 2, "12.5ma": 3}
PROXIMITY_LEVELS = {"1x": 0, "2x": 1, "4x": 2, "8x": 3}
AMBIENT_LEVELS = {"1x": 0, "4x": 1, "16x": 2, "64x": 3}
GESTURE_LEVELS = {"1x": 0, "2x": 1, "4x": 2, "8x": 3}
GESTURE_WAIT_TIMES = {
"0ms": 0,
"2.8ms": 1,
"5.6ms": 2,
"8.4ms": 3,
"14ms": 4,
"22.4ms": 5,
"30.8ms": 6,
"39.2ms": 7,
}
apds9960_nds = cg.esphome_ns.namespace("apds9960") apds9960_nds = cg.esphome_ns.namespace("apds9960")
APDS9960 = apds9960_nds.class_("APDS9960", cg.PollingComponent, i2c.I2CDevice) APDS9960 = apds9960_nds.class_("APDS9960", cg.PollingComponent, i2c.I2CDevice)
@@ -37,20 +16,6 @@ CONFIG_SCHEMA = (
cv.Schema( cv.Schema(
{ {
cv.GenerateID(): cv.declare_id(APDS9960), cv.GenerateID(): cv.declare_id(APDS9960),
cv.Optional(CONF_LED_DRIVE, "100mA"): cv.enum(DRIVE_LEVELS, lower=True),
cv.Optional(CONF_PROXIMITY_GAIN, "4x"): cv.enum(
PROXIMITY_LEVELS, lower=True
),
cv.Optional(CONF_AMBIENT_LIGHT_GAIN, "4x"): cv.enum(
AMBIENT_LEVELS, lower=True
),
cv.Optional(CONF_GESTURE_LED_DRIVE, "100mA"): cv.enum(
DRIVE_LEVELS, lower=True
),
cv.Optional(CONF_GESTURE_GAIN, "4x"): cv.enum(GESTURE_LEVELS, lower=True),
cv.Optional(CONF_GESTURE_WAIT_TIME, "2.8ms"): cv.enum(
GESTURE_WAIT_TIMES, lower=True
),
} }
) )
.extend(cv.polling_component_schema("60s")) .extend(cv.polling_component_schema("60s"))
@@ -62,9 +27,3 @@ async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config) await cg.register_component(var, config)
await i2c.register_i2c_device(var, config) await i2c.register_i2c_device(var, config)
cg.add(var.set_led_drive(config[CONF_LED_DRIVE]))
cg.add(var.set_proximity_gain(config[CONF_PROXIMITY_GAIN]))
cg.add(var.set_ambient_gain(config[CONF_AMBIENT_LIGHT_GAIN]))
cg.add(var.set_gesture_led_drive(config[CONF_GESTURE_LED_DRIVE]))
cg.add(var.set_gesture_gain(config[CONF_GESTURE_GAIN]))
cg.add(var.set_gesture_wait_time(config[CONF_GESTURE_WAIT_TIME]))

View File

@@ -23,7 +23,7 @@ void APDS9960::setup() {
return; return;
} }
if (id != 0xAB && id != 0x9C && id != 0xA8) { // APDS9960 all should have one of these IDs if (id != 0xAB && id != 0x9C) { // APDS9960 all should have one of these IDs
this->error_code_ = WRONG_ID; this->error_code_ = WRONG_ID;
this->mark_failed(); this->mark_failed();
return; return;
@@ -46,16 +46,16 @@ void APDS9960::setup() {
uint8_t val = 0; uint8_t val = 0;
APDS9960_ERROR_CHECK(this->read_byte(0x8F, &val)); APDS9960_ERROR_CHECK(this->read_byte(0x8F, &val));
val &= 0b00111111; val &= 0b00111111;
// led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA uint8_t led_drive = 0; // led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA
val |= (this->led_drive_ & 0b11) << 6; val |= (led_drive & 0b11) << 6;
val &= 0b11110011; val &= 0b11110011;
// proximity gain, 0 -> 1x, 1 -> 2X, 2 -> 4X, 3 -> 8X uint8_t proximity_gain = 2; // proximity gain, 0 -> 1x, 1 -> 2X, 2 -> 4X, 4 -> 8X
val |= (this->proximity_gain_ & 0b11) << 2; val |= (proximity_gain & 0b11) << 2;
val &= 0b11111100; val &= 0b11111100;
// ambient light gain, 0 -> 1x, 1 -> 4x, 2 -> 16x, 3 -> 64x uint8_t ambient_gain = 1; // ambient light gain, 0 -> 1x, 1 -> 4x, 2 -> 16x, 3 -> 64x
val |= (this->ambient_gain_ & 0b11) << 0; val |= (ambient_gain & 0b11) << 0;
APDS9960_WRITE_BYTE(0x8F, val); APDS9960_WRITE_BYTE(0x8F, val);
// Pers (0x8C) -> 0x11 (2 consecutive proximity or ALS for interrupt) // Pers (0x8C) -> 0x11 (2 consecutive proximity or ALS for interrupt)
@@ -75,18 +75,19 @@ void APDS9960::setup() {
// GConf 2 (0xA3, gesture config 2) -> // GConf 2 (0xA3, gesture config 2) ->
APDS9960_ERROR_CHECK(this->read_byte(0xA3, &val)); APDS9960_ERROR_CHECK(this->read_byte(0xA3, &val));
val &= 0b10011111; val &= 0b10011111;
// gesture gain, 0 -> 1x, 1 -> 2x, 2 -> 4x, 3 -> 8x uint8_t gesture_gain = 2; // gesture gain, 0 -> 1x, 1 -> 2x, 2 -> 4x, 3 -> 8x
val |= (this->gesture_gain_ & 0b11) << 5; val |= (gesture_gain & 0b11) << 5;
val &= 0b11100111; val &= 0b11100111;
// gesture led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA uint8_t gesture_led_drive = 0; // gesture led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA
val |= (this->gesture_led_drive_ & 0b11) << 3; val |= (gesture_led_drive & 0b11) << 3;
val &= 0b11111000; val &= 0b11111000;
// gesture wait time // gesture wait time
// 0 -> 0ms, 1 -> 2.8ms, 2 -> 5.6ms, 3 -> 8.4ms // 0 -> 0ms, 1 -> 2.8ms, 2 -> 5.6ms, 3 -> 8.4ms
// 4 -> 14.0ms, 5 -> 22.4 ms, 6 -> 30.8ms, 7 -> 39.2 ms // 4 -> 14.0ms, 5 -> 22.4 ms, 6 -> 30.8ms, 7 -> 39.2 ms
val |= (this->gesture_wait_time_ & 0b111) << 0; uint8_t gesture_wait_time = 1; // gesture wait time
val |= (gesture_wait_time & 0b111) << 0;
APDS9960_WRITE_BYTE(0xA3, val); APDS9960_WRITE_BYTE(0xA3, val);
// GOffsetU (0xA4) -> 0x00 (no offset) // GOffsetU (0xA4) -> 0x00 (no offset)

View File

@@ -16,13 +16,6 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice {
void update() override; void update() override;
void loop() override; void loop() override;
void set_led_drive(uint8_t level) { this->led_drive_ = level; }
void set_proximity_gain(uint8_t gain) { this->proximity_gain_ = gain; }
void set_ambient_gain(uint8_t gain) { this->ambient_gain_ = gain; }
void set_gesture_led_drive(uint8_t level) { this->gesture_led_drive_ = level; }
void set_gesture_gain(uint8_t gain) { this->gesture_gain_ = gain; }
void set_gesture_wait_time(uint8_t wait_time) { this->gesture_wait_time_ = wait_time; }
void set_red_channel(sensor::Sensor *red_channel) { red_channel_ = red_channel; } void set_red_channel(sensor::Sensor *red_channel) { red_channel_ = red_channel; }
void set_green_channel(sensor::Sensor *green_channel) { green_channel_ = green_channel; } void set_green_channel(sensor::Sensor *green_channel) { green_channel_ = green_channel; }
void set_blue_channel(sensor::Sensor *blue_channel) { blue_channel_ = blue_channel; } void set_blue_channel(sensor::Sensor *blue_channel) { blue_channel_ = blue_channel; }
@@ -43,13 +36,6 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice {
void report_gesture_(int gesture); void report_gesture_(int gesture);
void process_dataset_(int up, int down, int left, int right); void process_dataset_(int up, int down, int left, int right);
uint8_t led_drive_;
uint8_t proximity_gain_;
uint8_t ambient_gain_;
uint8_t gesture_led_drive_;
uint8_t gesture_gain_;
uint8_t gesture_wait_time_;
sensor::Sensor *red_channel_{nullptr}; sensor::Sensor *red_channel_{nullptr};
sensor::Sensor *green_channel_{nullptr}; sensor::Sensor *green_channel_{nullptr};
sensor::Sensor *blue_channel_{nullptr}; sensor::Sensor *blue_channel_{nullptr};

View File

@@ -42,17 +42,6 @@ service APIConnection {
rpc select_command (SelectCommandRequest) returns (void) {} rpc select_command (SelectCommandRequest) returns (void) {}
rpc button_command (ButtonCommandRequest) returns (void) {} rpc button_command (ButtonCommandRequest) returns (void) {}
rpc lock_command (LockCommandRequest) returns (void) {} rpc lock_command (LockCommandRequest) returns (void) {}
rpc media_player_command (MediaPlayerCommandRequest) returns (void) {}
rpc subscribe_bluetooth_le_advertisements(SubscribeBluetoothLEAdvertisementsRequest) returns (void) {}
rpc bluetooth_device_request(BluetoothDeviceRequest) returns (void) {}
rpc bluetooth_gatt_get_services(BluetoothGATTGetServicesRequest) returns (void) {}
rpc bluetooth_gatt_read(BluetoothGATTReadRequest) returns (void) {}
rpc bluetooth_gatt_write(BluetoothGATTWriteRequest) returns (void) {}
rpc bluetooth_gatt_read_descriptor(BluetoothGATTReadDescriptorRequest) returns (void) {}
rpc bluetooth_gatt_write_descriptor(BluetoothGATTWriteDescriptorRequest) returns (void) {}
rpc bluetooth_gatt_notify(BluetoothGATTNotifyRequest) returns (void) {}
rpc subscribe_bluetooth_connections_free(SubscribeBluetoothConnectionsFreeRequest) returns (BluetoothConnectionsFreeResponse) {}
} }
@@ -87,8 +76,6 @@ message HelloRequest {
// Not strictly necessary to send but nice for debugging // Not strictly necessary to send but nice for debugging
// purposes. // purposes.
string client_info = 1; string client_info = 1;
uint32 api_version_major = 2;
uint32 api_version_minor = 3;
} }
// Confirmation of successful connection request. // Confirmation of successful connection request.
@@ -202,12 +189,6 @@ message DeviceInfoResponse {
string project_version = 9; string project_version = 9;
uint32 webserver_port = 10; uint32 webserver_port = 10;
uint32 bluetooth_proxy_version = 11;
string manufacturer = 12;
string friendly_name = 13;
} }
message ListEntitiesRequest { message ListEntitiesRequest {
@@ -491,7 +472,6 @@ enum SensorStateClass {
STATE_CLASS_NONE = 0; STATE_CLASS_NONE = 0;
STATE_CLASS_MEASUREMENT = 1; STATE_CLASS_MEASUREMENT = 1;
STATE_CLASS_TOTAL_INCREASING = 2; STATE_CLASS_TOTAL_INCREASING = 2;
STATE_CLASS_TOTAL = 3;
} }
enum SensorLastResetType { enum SensorLastResetType {
@@ -787,7 +767,6 @@ enum ClimateFanMode {
CLIMATE_FAN_MIDDLE = 6; CLIMATE_FAN_MIDDLE = 6;
CLIMATE_FAN_FOCUS = 7; CLIMATE_FAN_FOCUS = 7;
CLIMATE_FAN_DIFFUSE = 8; CLIMATE_FAN_DIFFUSE = 8;
CLIMATE_FAN_QUIET = 9;
} }
enum ClimateSwingMode { enum ClimateSwingMode {
CLIMATE_SWING_OFF = 0; CLIMATE_SWING_OFF = 0;
@@ -829,7 +808,7 @@ message ListEntitiesClimateResponse {
repeated ClimateMode supported_modes = 7; repeated ClimateMode supported_modes = 7;
float visual_min_temperature = 8; float visual_min_temperature = 8;
float visual_max_temperature = 9; float visual_max_temperature = 9;
float visual_target_temperature_step = 10; float visual_temperature_step = 10;
// for older peer versions - in new system this // for older peer versions - in new system this
// is if CLIMATE_PRESET_AWAY exists is supported_presets // is if CLIMATE_PRESET_AWAY exists is supported_presets
bool legacy_supports_away = 11; bool legacy_supports_away = 11;
@@ -842,7 +821,6 @@ message ListEntitiesClimateResponse {
bool disabled_by_default = 18; bool disabled_by_default = 18;
string icon = 19; string icon = 19;
EntityCategory entity_category = 20; EntityCategory entity_category = 20;
float visual_current_temperature_step = 21;
} }
message ClimateStateResponse { message ClimateStateResponse {
option (id) = 47; option (id) = 47;
@@ -919,7 +897,6 @@ message ListEntitiesNumberResponse {
EntityCategory entity_category = 10; EntityCategory entity_category = 10;
string unit_of_measurement = 11; string unit_of_measurement = 11;
NumberMode mode = 12; NumberMode mode = 12;
string device_class = 13;
} }
message NumberStateResponse { message NumberStateResponse {
option (id) = 50; option (id) = 50;
@@ -1014,7 +991,7 @@ message ListEntitiesLockResponse {
bool supports_open = 9; bool supports_open = 9;
bool requires_code = 10; bool requires_code = 10;
// Not yet implemented: # Not yet implemented:
string code_format = 11; string code_format = 11;
} }
message LockStateResponse { message LockStateResponse {
@@ -1033,7 +1010,7 @@ message LockCommandRequest {
fixed32 key = 1; fixed32 key = 1;
LockCommand command = 2; LockCommand command = 2;
// Not yet implemented: # Not yet implemented:
bool has_code = 3; bool has_code = 3;
string code = 4; string code = 4;
} }
@@ -1063,299 +1040,3 @@ message ButtonCommandRequest {
fixed32 key = 1; fixed32 key = 1;
} }
// ==================== MEDIA PLAYER ====================
enum MediaPlayerState {
MEDIA_PLAYER_STATE_NONE = 0;
MEDIA_PLAYER_STATE_IDLE = 1;
MEDIA_PLAYER_STATE_PLAYING = 2;
MEDIA_PLAYER_STATE_PAUSED = 3;
}
enum MediaPlayerCommand {
MEDIA_PLAYER_COMMAND_PLAY = 0;
MEDIA_PLAYER_COMMAND_PAUSE = 1;
MEDIA_PLAYER_COMMAND_STOP = 2;
MEDIA_PLAYER_COMMAND_MUTE = 3;
MEDIA_PLAYER_COMMAND_UNMUTE = 4;
}
message ListEntitiesMediaPlayerResponse {
option (id) = 63;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_MEDIA_PLAYER";
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 supports_pause = 8;
}
message MediaPlayerStateResponse {
option (id) = 64;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_MEDIA_PLAYER";
option (no_delay) = true;
fixed32 key = 1;
MediaPlayerState state = 2;
float volume = 3;
bool muted = 4;
}
message MediaPlayerCommandRequest {
option (id) = 65;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_MEDIA_PLAYER";
option (no_delay) = true;
fixed32 key = 1;
bool has_command = 2;
MediaPlayerCommand command = 3;
bool has_volume = 4;
float volume = 5;
bool has_media_url = 6;
string media_url = 7;
}
// ==================== BLUETOOTH ====================
message SubscribeBluetoothLEAdvertisementsRequest {
option (id) = 66;
option (source) = SOURCE_CLIENT;
}
message BluetoothServiceData {
string uuid = 1;
repeated uint32 legacy_data = 2 [deprecated = true];
bytes data = 3; // Changed in proto version 1.7
}
message BluetoothLEAdvertisementResponse {
option (id) = 67;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
option (no_delay) = true;
uint64 address = 1;
string name = 2;
sint32 rssi = 3;
repeated string service_uuids = 4;
repeated BluetoothServiceData service_data = 5;
repeated BluetoothServiceData manufacturer_data = 6;
uint32 address_type = 7;
}
enum BluetoothDeviceRequestType {
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT = 0;
BLUETOOTH_DEVICE_REQUEST_TYPE_DISCONNECT = 1;
BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR = 2;
BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR = 3;
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE = 4;
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5;
}
message BluetoothDeviceRequest {
option (id) = 68;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
BluetoothDeviceRequestType request_type = 2;
bool has_address_type = 3;
uint32 address_type = 4;
}
message BluetoothDeviceConnectionResponse {
option (id) = 69;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
bool connected = 2;
uint32 mtu = 3;
int32 error = 4;
}
message BluetoothGATTGetServicesRequest {
option (id) = 70;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
}
message BluetoothGATTDescriptor {
repeated uint64 uuid = 1;
uint32 handle = 2;
}
message BluetoothGATTCharacteristic {
repeated uint64 uuid = 1;
uint32 handle = 2;
uint32 properties = 3;
repeated BluetoothGATTDescriptor descriptors = 4;
}
message BluetoothGATTService {
repeated uint64 uuid = 1;
uint32 handle = 2;
repeated BluetoothGATTCharacteristic characteristics = 3;
}
message BluetoothGATTGetServicesResponse {
option (id) = 71;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
repeated BluetoothGATTService services = 2;
}
message BluetoothGATTGetServicesDoneResponse {
option (id) = 72;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
}
message BluetoothGATTReadRequest {
option (id) = 73;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
}
message BluetoothGATTReadResponse {
option (id) = 74;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
bytes data = 3;
}
message BluetoothGATTWriteRequest {
option (id) = 75;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
bool response = 3;
bytes data = 4;
}
message BluetoothGATTReadDescriptorRequest {
option (id) = 76;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
}
message BluetoothGATTWriteDescriptorRequest {
option (id) = 77;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
bytes data = 3;
}
message BluetoothGATTNotifyRequest {
option (id) = 78;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
bool enable = 3;
}
message BluetoothGATTNotifyDataResponse {
option (id) = 79;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
bytes data = 3;
}
message SubscribeBluetoothConnectionsFreeRequest {
option (id) = 80;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
}
message BluetoothConnectionsFreeResponse {
option (id) = 81;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint32 free = 1;
uint32 limit = 2;
}
message BluetoothGATTErrorResponse {
option (id) = 82;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
int32 error = 3;
}
message BluetoothGATTWriteResponse {
option (id) = 83;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
}
message BluetoothGATTNotifyResponse {
option (id) = 84;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
uint32 handle = 2;
}
message BluetoothDevicePairingResponse {
option (id) = 85;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
bool paired = 2;
int32 error = 3;
}
message BluetoothDeviceUnpairingResponse {
option (id) = 86;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
bool success = 2;
int32 error = 3;
}

View File

@@ -1,10 +1,10 @@
#include "api_connection.h" #include "api_connection.h"
#include <cerrno>
#include "esphome/components/network/util.h"
#include "esphome/core/entity_base.h" #include "esphome/core/entity_base.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/components/network/util.h"
#include "esphome/core/version.h" #include "esphome/core/version.h"
#include "esphome/core/hal.h"
#include <cerrno>
#ifdef USE_DEEP_SLEEP #ifdef USE_DEEP_SLEEP
#include "esphome/components/deep_sleep/deep_sleep_component.h" #include "esphome/components/deep_sleep/deep_sleep_component.h"
@@ -12,9 +12,6 @@
#ifdef USE_HOMEASSISTANT_TIME #ifdef USE_HOMEASSISTANT_TIME
#include "esphome/components/homeassistant/time/homeassistant_time.h" #include "esphome/components/homeassistant/time/homeassistant_time.h"
#endif #endif
#ifdef USE_BLUETOOTH_PROXY
#include "esphome/components/bluetooth_proxy/bluetooth_proxy.h"
#endif
namespace esphome { namespace esphome {
namespace api { namespace api {
@@ -548,9 +545,7 @@ bool APIConnection::send_climate_info(climate::Climate *climate) {
msg.visual_min_temperature = traits.get_visual_min_temperature(); msg.visual_min_temperature = traits.get_visual_min_temperature();
msg.visual_max_temperature = traits.get_visual_max_temperature(); msg.visual_max_temperature = traits.get_visual_max_temperature();
msg.visual_target_temperature_step = traits.get_visual_target_temperature_step(); msg.visual_temperature_step = traits.get_visual_temperature_step();
msg.visual_current_temperature_step = traits.get_visual_current_temperature_step();
msg.legacy_supports_away = traits.supports_preset(climate::CLIMATE_PRESET_AWAY); msg.legacy_supports_away = traits.supports_preset(climate::CLIMATE_PRESET_AWAY);
msg.supports_action = traits.get_supports_action(); msg.supports_action = traits.get_supports_action();
@@ -618,7 +613,6 @@ bool APIConnection::send_number_info(number::Number *number) {
msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category()); msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category());
msg.unit_of_measurement = number->traits.get_unit_of_measurement(); msg.unit_of_measurement = number->traits.get_unit_of_measurement();
msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode()); msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
msg.device_class = number->traits.get_device_class();
msg.min_value = number->traits.get_min_value(); msg.min_value = number->traits.get_min_value();
msg.max_value = number->traits.get_max_value(); msg.max_value = number->traits.get_max_value();
@@ -739,52 +733,6 @@ void APIConnection::lock_command(const LockCommandRequest &msg) {
} }
#endif #endif
#ifdef USE_MEDIA_PLAYER
bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
if (!this->state_subscription_)
return false;
MediaPlayerStateResponse resp{};
resp.key = media_player->get_object_id_hash();
resp.state = static_cast<enums::MediaPlayerState>(media_player->state);
resp.volume = media_player->volume;
resp.muted = media_player->is_muted();
return this->send_media_player_state_response(resp);
}
bool APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
ListEntitiesMediaPlayerResponse msg;
msg.key = media_player->get_object_id_hash();
msg.object_id = media_player->get_object_id();
msg.name = media_player->get_name();
msg.unique_id = get_default_unique_id("media_player", media_player);
msg.icon = media_player->get_icon();
msg.disabled_by_default = media_player->is_disabled_by_default();
msg.entity_category = static_cast<enums::EntityCategory>(media_player->get_entity_category());
auto traits = media_player->get_traits();
msg.supports_pause = traits.get_supports_pause();
return this->send_list_entities_media_player_response(msg);
}
void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
media_player::MediaPlayer *media_player = App.get_media_player_by_key(msg.key);
if (media_player == nullptr)
return;
auto call = media_player->make_call();
if (msg.has_command) {
call.set_command(static_cast<media_player::MediaPlayerCommand>(msg.command));
}
if (msg.has_volume) {
call.set_volume(msg.volume);
}
if (msg.has_media_url) {
call.set_media_url(msg.media_url);
}
call.perform();
}
#endif
#ifdef USE_ESP32_CAMERA #ifdef USE_ESP32_CAMERA
void APIConnection::send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image) { void APIConnection::send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image) {
if (!this->state_subscription_) if (!this->state_subscription_)
@@ -829,56 +777,6 @@ void APIConnection::on_get_time_response(const GetTimeResponse &value) {
} }
#endif #endif
#ifdef USE_BLUETOOTH_PROXY
bool APIConnection::send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg) {
if (!this->bluetooth_le_advertisement_subscription_)
return false;
if (this->client_api_version_major_ < 1 || this->client_api_version_minor_ < 7) {
BluetoothLEAdvertisementResponse resp = msg;
for (auto &service : resp.service_data) {
service.legacy_data.assign(service.data.begin(), service.data.end());
service.data.clear();
}
for (auto &manufacturer_data : resp.manufacturer_data) {
manufacturer_data.legacy_data.assign(manufacturer_data.data.begin(), manufacturer_data.data.end());
manufacturer_data.data.clear();
}
return this->send_bluetooth_le_advertisement_response(resp);
}
return this->send_bluetooth_le_advertisement_response(msg);
}
void APIConnection::bluetooth_device_request(const BluetoothDeviceRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_device_request(msg);
}
void APIConnection::bluetooth_gatt_read(const BluetoothGATTReadRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_read(msg);
}
void APIConnection::bluetooth_gatt_write(const BluetoothGATTWriteRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_write(msg);
}
void APIConnection::bluetooth_gatt_read_descriptor(const BluetoothGATTReadDescriptorRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_read_descriptor(msg);
}
void APIConnection::bluetooth_gatt_write_descriptor(const BluetoothGATTWriteDescriptorRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_write_descriptor(msg);
}
void APIConnection::bluetooth_gatt_get_services(const BluetoothGATTGetServicesRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_send_services(msg);
}
void APIConnection::bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) {
bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_notify(msg);
}
BluetoothConnectionsFreeResponse APIConnection::subscribe_bluetooth_connections_free(
const SubscribeBluetoothConnectionsFreeRequest &msg) {
BluetoothConnectionsFreeResponse resp;
resp.free = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_free();
resp.limit = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_limit();
return resp;
}
#endif
bool APIConnection::send_log_message(int level, const char *tag, const char *line) { bool APIConnection::send_log_message(int level, const char *tag, const char *line) {
if (this->log_subscription_ < level) if (this->log_subscription_ < level)
return false; return false;
@@ -896,14 +794,11 @@ bool APIConnection::send_log_message(int level, const char *tag, const char *lin
HelloResponse APIConnection::hello(const HelloRequest &msg) { HelloResponse APIConnection::hello(const HelloRequest &msg) {
this->client_info_ = msg.client_info + " (" + this->helper_->getpeername() + ")"; this->client_info_ = msg.client_info + " (" + this->helper_->getpeername() + ")";
this->helper_->set_log_info(client_info_); this->helper_->set_log_info(client_info_);
this->client_api_version_major_ = msg.api_version_major; ESP_LOGV(TAG, "Hello from client: '%s'", this->client_info_.c_str());
this->client_api_version_minor_ = msg.api_version_minor;
ESP_LOGV(TAG, "Hello from client: '%s' | API Version %d.%d", this->client_info_.c_str(),
this->client_api_version_major_, this->client_api_version_minor_);
HelloResponse resp; HelloResponse resp;
resp.api_version_major = 1; resp.api_version_major = 1;
resp.api_version_minor = 7; resp.api_version_minor = 6;
resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")"; resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
resp.name = App.get_name(); resp.name = App.get_name();
@@ -932,15 +827,9 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
DeviceInfoResponse resp{}; DeviceInfoResponse resp{};
resp.uses_password = this->parent_->uses_password(); resp.uses_password = this->parent_->uses_password();
resp.name = App.get_name(); resp.name = App.get_name();
resp.friendly_name = App.get_friendly_name();
resp.mac_address = get_mac_address_pretty(); resp.mac_address = get_mac_address_pretty();
resp.esphome_version = ESPHOME_VERSION; resp.esphome_version = ESPHOME_VERSION;
resp.compilation_time = App.get_compilation_time(); resp.compilation_time = App.get_compilation_time();
#if defined(USE_ESP8266) || defined(USE_ESP32)
resp.manufacturer = "Espressif";
#elif defined(USE_RP2040)
resp.manufacturer = "Raspberry Pi";
#endif
resp.model = ESPHOME_BOARD; resp.model = ESPHOME_BOARD;
#ifdef USE_DEEP_SLEEP #ifdef USE_DEEP_SLEEP
resp.has_deep_sleep = deep_sleep::global_has_deep_sleep; resp.has_deep_sleep = deep_sleep::global_has_deep_sleep;
@@ -951,9 +840,6 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
#endif #endif
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
resp.webserver_port = USE_WEBSERVER_PORT; resp.webserver_port = USE_WEBSERVER_PORT;
#endif
#ifdef USE_BLUETOOTH_PROXY
resp.bluetooth_proxy_version = bluetooth_proxy::global_bluetooth_proxy->has_active() ? 4 : 1;
#endif #endif
return resp; return resp;
} }

View File

@@ -1,13 +1,11 @@
#pragma once #pragma once
#include "api_frame_helper.h" #include "esphome/core/component.h"
#include "esphome/core/application.h"
#include "api_pb2.h" #include "api_pb2.h"
#include "api_pb2_service.h" #include "api_pb2_service.h"
#include "api_server.h" #include "api_server.h"
#include "esphome/core/application.h" #include "api_frame_helper.h"
#include "esphome/core/component.h"
#include <vector>
namespace esphome { namespace esphome {
namespace api { namespace api {
@@ -84,11 +82,6 @@ class APIConnection : public APIServerConnection {
bool send_lock_state(lock::Lock *a_lock, lock::LockState state); bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
bool send_lock_info(lock::Lock *a_lock); bool send_lock_info(lock::Lock *a_lock);
void lock_command(const LockCommandRequest &msg) override; void lock_command(const LockCommandRequest &msg) override;
#endif
#ifdef USE_MEDIA_PLAYER
bool send_media_player_state(media_player::MediaPlayer *media_player);
bool send_media_player_info(media_player::MediaPlayer *media_player);
void media_player_command(const MediaPlayerCommandRequest &msg) override;
#endif #endif
bool send_log_message(int level, const char *tag, const char *line); bool send_log_message(int level, const char *tag, const char *line);
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) { void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
@@ -96,20 +89,6 @@ class APIConnection : public APIServerConnection {
return; return;
this->send_homeassistant_service_response(call); this->send_homeassistant_service_response(call);
} }
#ifdef USE_BLUETOOTH_PROXY
bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg);
void bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
void bluetooth_gatt_read(const BluetoothGATTReadRequest &msg) override;
void bluetooth_gatt_write(const BluetoothGATTWriteRequest &msg) override;
void bluetooth_gatt_read_descriptor(const BluetoothGATTReadDescriptorRequest &msg) override;
void bluetooth_gatt_write_descriptor(const BluetoothGATTWriteDescriptorRequest &msg) override;
void bluetooth_gatt_get_services(const BluetoothGATTGetServicesRequest &msg) override;
void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) override;
BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(
const SubscribeBluetoothConnectionsFreeRequest &msg) override;
#endif
#ifdef USE_HOMEASSISTANT_TIME #ifdef USE_HOMEASSISTANT_TIME
void send_time_request() { void send_time_request() {
GetTimeRequest req; GetTimeRequest req;
@@ -150,9 +129,6 @@ class APIConnection : public APIServerConnection {
return {}; return {};
} }
void execute_service(const ExecuteServiceRequest &msg) override; void execute_service(const ExecuteServiceRequest &msg) override;
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override {
this->bluetooth_le_advertisement_subscription_ = true;
}
bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; } bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; }
bool is_connection_setup() override { bool is_connection_setup() override {
return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated(); return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated();
@@ -186,8 +162,6 @@ class APIConnection : public APIServerConnection {
std::unique_ptr<APIFrameHelper> helper_; std::unique_ptr<APIFrameHelper> helper_;
std::string client_info_; std::string client_info_;
uint32_t client_api_version_major_{0};
uint32_t client_api_version_minor_{0};
#ifdef USE_ESP32_CAMERA #ifdef USE_ESP32_CAMERA
esp32_camera::CameraImageReader image_reader_; esp32_camera::CameraImageReader image_reader_;
#endif #endif
@@ -197,7 +171,6 @@ class APIConnection : public APIServerConnection {
uint32_t last_traffic_; uint32_t last_traffic_;
bool sent_ping_{false}; bool sent_ping_{false};
bool service_call_subscription_{false}; bool service_call_subscription_{false};
bool bluetooth_le_advertisement_subscription_{false};
bool next_close_ = false; bool next_close_ = false;
APIServer *parent_; APIServer *parent_;
InitialStateIterator initial_state_iterator_; InitialStateIterator initial_state_iterator_;

View File

@@ -270,7 +270,7 @@ APIError APINoiseFrameHelper::try_read_frame_(ParsedFrame *frame) {
* *
* If the handshake is still active when this method returns and a read/write can't take place at * If the handshake is still active when this method returns and a read/write can't take place at
* the moment, returns WOULD_BLOCK. * the moment, returns WOULD_BLOCK.
* If an error occurred, returns that error. Only returns OK if the transport is ready for data * If an error occured, returns that error. Only returns OK if the transport is ready for data
* traffic. * traffic.
*/ */
APIError APINoiseFrameHelper::state_action_() { APIError APINoiseFrameHelper::state_action_() {
@@ -586,7 +586,7 @@ APIError APINoiseFrameHelper::write_raw_(const struct iovec *iov, int iovcnt) {
} }
return APIError::OK; return APIError::OK;
} else if (sent == -1) { } else if (sent == -1) {
// an error occurred // an error occured
state_ = State::FAILED; state_ = State::FAILED;
HELPER_LOG("Socket write failed with errno %d", errno); HELPER_LOG("Socket write failed with errno %d", errno);
return APIError::SOCKET_WRITE_FAILED; return APIError::SOCKET_WRITE_FAILED;
@@ -616,9 +616,6 @@ APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, size_t len) {
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = header; iov[0].iov_base = header;
iov[0].iov_len = 3; iov[0].iov_len = 3;
if (len == 0) {
return write_raw_(iov, 1);
}
iov[1].iov_base = const_cast<uint8_t *>(data); iov[1].iov_base = const_cast<uint8_t *>(data);
iov[1].iov_len = len; iov[1].iov_len = len;
@@ -916,9 +913,6 @@ APIError APIPlaintextFrameHelper::write_packet(uint16_t type, const uint8_t *pay
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = &header[0]; iov[0].iov_base = &header[0];
iov[0].iov_len = header.size(); iov[0].iov_len = header.size();
if (payload_len == 0) {
return write_raw_(iov, 1);
}
iov[1].iov_base = const_cast<uint8_t *>(payload); iov[1].iov_base = const_cast<uint8_t *>(payload);
iov[1].iov_len = payload_len; iov[1].iov_len = payload_len;
@@ -986,7 +980,7 @@ APIError APIPlaintextFrameHelper::write_raw_(const struct iovec *iov, int iovcnt
} }
return APIError::OK; return APIError::OK;
} else if (sent == -1) { } else if (sent == -1) {
// an error occurred // an error occured
state_ = State::FAILED; state_ = State::FAILED;
HELPER_LOG("Socket write failed with errno %d", errno); HELPER_LOG("Socket write failed with errno %d", errno);
return APIError::SOCKET_WRITE_FAILED; return APIError::SOCKET_WRITE_FAILED;

View File

@@ -116,9 +116,9 @@ class APINoiseFrameHelper : public APIFrameHelper {
std::vector<uint8_t> prologue_; std::vector<uint8_t> prologue_;
std::shared_ptr<APINoiseContext> ctx_; std::shared_ptr<APINoiseContext> ctx_;
NoiseHandshakeState *handshake_{nullptr}; NoiseHandshakeState *handshake_ = nullptr;
NoiseCipherState *send_cipher_{nullptr}; NoiseCipherState *send_cipher_ = nullptr;
NoiseCipherState *recv_cipher_{nullptr}; NoiseCipherState *recv_cipher_ = nullptr;
NoiseProtocolId nid_; NoiseProtocolId nid_;
enum class State { enum class State {

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,6 @@ enum SensorStateClass : uint32_t {
STATE_CLASS_NONE = 0, STATE_CLASS_NONE = 0,
STATE_CLASS_MEASUREMENT = 1, STATE_CLASS_MEASUREMENT = 1,
STATE_CLASS_TOTAL_INCREASING = 2, STATE_CLASS_TOTAL_INCREASING = 2,
STATE_CLASS_TOTAL = 3,
}; };
enum SensorLastResetType : uint32_t { enum SensorLastResetType : uint32_t {
LAST_RESET_NONE = 0, LAST_RESET_NONE = 0,
@@ -99,7 +98,6 @@ enum ClimateFanMode : uint32_t {
CLIMATE_FAN_MIDDLE = 6, CLIMATE_FAN_MIDDLE = 6,
CLIMATE_FAN_FOCUS = 7, CLIMATE_FAN_FOCUS = 7,
CLIMATE_FAN_DIFFUSE = 8, CLIMATE_FAN_DIFFUSE = 8,
CLIMATE_FAN_QUIET = 9,
}; };
enum ClimateSwingMode : uint32_t { enum ClimateSwingMode : uint32_t {
CLIMATE_SWING_OFF = 0, CLIMATE_SWING_OFF = 0,
@@ -143,35 +141,12 @@ enum LockCommand : uint32_t {
LOCK_LOCK = 1, LOCK_LOCK = 1,
LOCK_OPEN = 2, LOCK_OPEN = 2,
}; };
enum MediaPlayerState : uint32_t {
MEDIA_PLAYER_STATE_NONE = 0,
MEDIA_PLAYER_STATE_IDLE = 1,
MEDIA_PLAYER_STATE_PLAYING = 2,
MEDIA_PLAYER_STATE_PAUSED = 3,
};
enum MediaPlayerCommand : uint32_t {
MEDIA_PLAYER_COMMAND_PLAY = 0,
MEDIA_PLAYER_COMMAND_PAUSE = 1,
MEDIA_PLAYER_COMMAND_STOP = 2,
MEDIA_PLAYER_COMMAND_MUTE = 3,
MEDIA_PLAYER_COMMAND_UNMUTE = 4,
};
enum BluetoothDeviceRequestType : uint32_t {
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT = 0,
BLUETOOTH_DEVICE_REQUEST_TYPE_DISCONNECT = 1,
BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR = 2,
BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR = 3,
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE = 4,
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5,
};
} // namespace enums } // namespace enums
class HelloRequest : public ProtoMessage { class HelloRequest : public ProtoMessage {
public: public:
std::string client_info{}; std::string client_info{};
uint32_t api_version_major{0};
uint32_t api_version_minor{0};
void encode(ProtoWriteBuffer buffer) const override; void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP #ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override; void dump_to(std::string &out) const override;
@@ -179,7 +154,6 @@ class HelloRequest : public ProtoMessage {
protected: protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override; bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
}; };
class HelloResponse : public ProtoMessage { class HelloResponse : public ProtoMessage {
public: public:
@@ -275,9 +249,6 @@ class DeviceInfoResponse : public ProtoMessage {
std::string project_name{}; std::string project_name{};
std::string project_version{}; std::string project_version{};
uint32_t webserver_port{0}; uint32_t webserver_port{0};
uint32_t bluetooth_proxy_version{0};
std::string manufacturer{};
std::string friendly_name{};
void encode(ProtoWriteBuffer buffer) const override; void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP #ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override; void dump_to(std::string &out) const override;
@@ -915,7 +886,7 @@ class ListEntitiesClimateResponse : public ProtoMessage {
std::vector<enums::ClimateMode> supported_modes{}; std::vector<enums::ClimateMode> supported_modes{};
float visual_min_temperature{0.0f}; float visual_min_temperature{0.0f};
float visual_max_temperature{0.0f}; float visual_max_temperature{0.0f};
float visual_target_temperature_step{0.0f}; float visual_temperature_step{0.0f};
bool legacy_supports_away{false}; bool legacy_supports_away{false};
bool supports_action{false}; bool supports_action{false};
std::vector<enums::ClimateFanMode> supported_fan_modes{}; std::vector<enums::ClimateFanMode> supported_fan_modes{};
@@ -926,7 +897,6 @@ class ListEntitiesClimateResponse : public ProtoMessage {
bool disabled_by_default{false}; bool disabled_by_default{false};
std::string icon{}; std::string icon{};
enums::EntityCategory entity_category{}; enums::EntityCategory entity_category{};
float visual_current_temperature_step{0.0f};
void encode(ProtoWriteBuffer buffer) const override; void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP #ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override; void dump_to(std::string &out) const override;
@@ -1009,7 +979,6 @@ class ListEntitiesNumberResponse : public ProtoMessage {
enums::EntityCategory entity_category{}; enums::EntityCategory entity_category{};
std::string unit_of_measurement{}; std::string unit_of_measurement{};
enums::NumberMode mode{}; enums::NumberMode mode{};
std::string device_class{};
void encode(ProtoWriteBuffer buffer) const override; void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP #ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override; void dump_to(std::string &out) const override;
@@ -1177,383 +1146,6 @@ class ButtonCommandRequest : public ProtoMessage {
protected: protected:
bool decode_32bit(uint32_t field_id, Proto32Bit value) override; bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
}; };
class ListEntitiesMediaPlayerResponse : 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 supports_pause{false};
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 MediaPlayerStateResponse : public ProtoMessage {
public:
uint32_t key{0};
enums::MediaPlayerState state{};
float volume{0.0f};
bool muted{false};
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 MediaPlayerCommandRequest : public ProtoMessage {
public:
uint32_t key{0};
bool has_command{false};
enums::MediaPlayerCommand command{};
bool has_volume{false};
float volume{0.0f};
bool has_media_url{false};
std::string media_url{};
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 SubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
public:
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
};
class BluetoothServiceData : public ProtoMessage {
public:
std::string uuid{};
std::vector<uint32_t> legacy_data{};
std::string data{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothLEAdvertisementResponse : public ProtoMessage {
public:
uint64_t address{0};
std::string name{};
int32_t rssi{0};
std::vector<std::string> service_uuids{};
std::vector<BluetoothServiceData> service_data{};
std::vector<BluetoothServiceData> manufacturer_data{};
uint32_t address_type{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothDeviceRequest : public ProtoMessage {
public:
uint64_t address{0};
enums::BluetoothDeviceRequestType request_type{};
bool has_address_type{false};
uint32_t address_type{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothDeviceConnectionResponse : public ProtoMessage {
public:
uint64_t address{0};
bool connected{false};
uint32_t mtu{0};
int32_t error{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTGetServicesRequest : public ProtoMessage {
public:
uint64_t address{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTDescriptor : public ProtoMessage {
public:
std::vector<uint64_t> uuid{};
uint32_t handle{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTCharacteristic : public ProtoMessage {
public:
std::vector<uint64_t> uuid{};
uint32_t handle{0};
uint32_t properties{0};
std::vector<BluetoothGATTDescriptor> descriptors{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTService : public ProtoMessage {
public:
std::vector<uint64_t> uuid{};
uint32_t handle{0};
std::vector<BluetoothGATTCharacteristic> characteristics{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTGetServicesResponse : public ProtoMessage {
public:
uint64_t address{0};
std::vector<BluetoothGATTService> services{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTGetServicesDoneResponse : public ProtoMessage {
public:
uint64_t address{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTReadRequest : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTReadResponse : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
std::string data{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTWriteRequest : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
bool response{false};
std::string data{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTReadDescriptorRequest : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTWriteDescriptorRequest : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
std::string data{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTNotifyRequest : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
bool enable{false};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTNotifyDataResponse : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
std::string data{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class SubscribeBluetoothConnectionsFreeRequest : public ProtoMessage {
public:
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
};
class BluetoothConnectionsFreeResponse : public ProtoMessage {
public:
uint32_t free{0};
uint32_t limit{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTErrorResponse : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
int32_t error{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTWriteResponse : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothGATTNotifyResponse : public ProtoMessage {
public:
uint64_t address{0};
uint32_t handle{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothDevicePairingResponse : public ProtoMessage {
public:
uint64_t address{0};
bool paired{false};
int32_t error{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class BluetoothDeviceUnpairingResponse : public ProtoMessage {
public:
uint64_t address{0};
bool success{false};
int32_t error{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
#endif
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
} // namespace api } // namespace api
} // namespace esphome } // namespace esphome

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