1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-01 15:41:52 +00:00

Compare commits

...

358 Commits

Author SHA1 Message Date
Jesse Hills
b8c27bc17d Merge pull request #4905 from esphome/bump-2023.5.5
2023.5.5
2023-05-29 10:25:22 +12:00
Jesse Hills
1057ac4db7 Bump version to 2023.5.5 2023-05-29 09:42:12 +12:00
Jesse Hills
69f5674d9e Fix version printing not breaking yaml parsing (#4904) 2023-05-29 09:42:12 +12:00
Keith Burzinski
b723728177 Merge pull request #4889 from esphome/bump-2023.5.4
2023.5.4
2023-05-24 17:21:24 -05:00
Keith Burzinski
316171491f Bump version to 2023.5.4 2023-05-24 15:58:54 -05:00
Jesse Hills
91ff502872 Fix esp32_rmt_led_strip color modes (#4886) 2023-05-24 15:58:53 -05:00
Samuel Sieb
6e414180e0 fix modbus sending FP32_R values (#4882) 2023-05-24 15:58:53 -05:00
Jesse Hills
7d2ae4e252 Print ESPHome version when running commands (#4883) 2023-05-24 15:58:53 -05:00
Davrosx
fb4cb07c6f Update cover.h for compile errors with stop() (#4879) 2023-05-24 15:58:53 -05:00
Fabian
19f91a7deb [internal_temperature] ESP32-S3 needs ESP IDF V4.4.3 or higher (#4873)
Co-authored-by: Your Name <you@example.com>
2023-05-24 15:58:53 -05:00
Keith Burzinski
3807350c61 Merge pull request #4877 from esphome/bump-2023.5.3
2023.5.3
2023-05-22 17:25:56 -05:00
Keith Burzinski
9d2467cf62 Bump version to 2023.5.3 2023-05-22 16:53:10 -05:00
Fabian
d2480d3194 [PSRam] Change log unit to KB to minimize rounding error. (#4872)
Co-authored-by: Your Name <you@example.com>
2023-05-22 16:53:10 -05:00
Jesse Hills
148eb03d13 Allow microphone channel to be specified in config (#4871) 2023-05-22 16:53:10 -05:00
Jesse Hills
70aa5d0f6c Merge pull request #4870 from esphome/bump-2023.5.2
2023.5.2
2023-05-22 12:15:07 +12:00
Jesse Hills
8fcec8e2cb Bump version to 2023.5.2 2023-05-22 11:31:30 +12:00
Stefan Rado
2d3b48f86f Fix i2s_audio media_player mutex acquisition (#4867)
Co-authored-by: Rajan Patel <rpatel3001@gmail.com>
2023-05-22 11:31:30 +12:00
Jesse Hills
99c10bc6de Merge pull request #4852 from esphome/bump-2023.5.1
2023.5.1
2023-05-18 14:27:55 +12:00
Jesse Hills
f30f20db86 Bump version to 2023.5.1 2023-05-18 13:00:37 +12:00
Keith Burzinski
9bf946e196 Sprinkler fixes (#4816) 2023-05-18 13:00:36 +12:00
Jesse Hills
bfaad1f28d Remove i2c dependency from ttp229_bsf (#4851) 2023-05-18 13:00:36 +12:00
Jesse Hills
f90e9ba871 Merge pull request #4846 from esphome/bump-2023.5.0
2023.5.0
2023-05-17 13:17:10 +12:00
Jesse Hills
726bdd7be2 Bump version to 2023.5.0 2023-05-17 12:45:42 +12:00
Jesse Hills
52db40eb41 Merge pull request #4845 from esphome/bump-2023.5.0b5
2023.5.0b5
2023-05-17 12:04:22 +12:00
Jesse Hills
3c371a0c59 Bump version to 2023.5.0b5 2023-05-17 09:57:36 +12:00
Samuel Sieb
c941bc4109 handle Wiegand 8-bit keys (#4837)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2023-05-17 09:57:35 +12:00
Samuel Sieb
cc76e5353c support sending keys to the collector (#4838)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2023-05-17 09:57:35 +12:00
Jesse Hills
11bb46e393 Merge pull request #4835 from esphome/bump-2023.5.0b4
2023.5.0b4
2023-05-16 12:00:39 +12:00
Jesse Hills
71c4714a6e Bump version to 2023.5.0b4 2023-05-16 11:16:14 +12:00
github-actions[bot]
a4e63c5f86 Synchronise Device Classes from Home Assistant (#4825)
Co-authored-by: esphomebot <esphome@nabucasa.com>
2023-05-16 11:16:14 +12:00
Justin Gerace
c71e7d0132 Start UART assignment at UART0 if the logger is not enabled or is not configured for hardware logging on ESP32 (#4762) 2023-05-16 11:16:13 +12:00
dependabot[bot]
daa966975e Bump tzlocal from 4.2 to 5.0.1 (#4829)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-16 11:16:13 +12:00
Federico G. Schwindt
2e5757a3f0 Fix time period validation for the auto cleaning interval (#4811) 2023-05-16 11:16:13 +12:00
Jesse Hills
f66024b37c Bump esphome-dashboard to 20230516.0 (#4831) 2023-05-16 11:16:13 +12:00
Christian
c16ca7be13 Update PulseLightEffect with range brightness (#4820)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-05-16 11:16:13 +12:00
dependabot[bot]
e13e754bc4 Bump aioesphomeapi from 13.7.2 to 13.7.5 (#4830)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-16 11:16:13 +12:00
RoboMagus
6ccea59f71 Fix missing stop trait in send_cover_info (#4826) 2023-05-16 11:16:13 +12:00
Jesse Hills
71b28be3c8 Merge pull request #4822 from esphome/bump-2023.5.0b3
2023.5.0b3
2023-05-15 13:06:10 +12:00
Jesse Hills
e25d92e1f5 Bump version to 2023.5.0b3 2023-05-15 11:37:55 +12:00
Jesse Hills
65cda10884 Dontr try stop if not actually started (#4814) 2023-05-15 11:37:55 +12:00
Jesse Hills
625126df68 Fix i2s media player volume control (#4813) 2023-05-15 11:37:55 +12:00
richardhopton
e0ee8ca17c Tuya: Prevent loop when setting colors on case-sensitive dps (#4809)
Co-authored-by: Samuel Sieb <samuel-github@sieb.net>
2023-05-15 11:37:54 +12:00
Federico G. Schwindt
af95e781f5 Wording (#4805) 2023-05-15 11:37:54 +12:00
Jesse Hills
9b230a7d93 Merge pull request #4808 from esphome/bump-2023.5.0b2
2023.5.0b2
2023-05-12 11:02:45 +12:00
Jesse Hills
e2f3e7c3a6 Bump version to 2023.5.0b2 2023-05-12 10:32:59 +12:00
Alex Dekker
2fd2e5ceb2 Supposed to fix #4069, by changing the default value to 0s (timeunit instead of int) to pass validation (#4806)
Co-authored-by: Alex1602 <alex1602@gmail.com>
2023-05-12 10:32:59 +12:00
Jesse Hills
d88358be8e Remove AUTO_LOAD from apds9960 (#4746) 2023-05-12 10:32:59 +12:00
Jimmy Hedman
d80885c7a8 Fixed access point for ESP32 IDF platform (#4784) 2023-05-12 10:32:59 +12:00
Jesse Hills
c7c9c49f4e Merge pull request #4803 from esphome/bump-2023.5.0b1
2023.5.0b1
2023-05-11 10:54:30 +12:00
Jesse Hills
2c160a8a25 Bump version to 2023.5.0b1 2023-05-11 09:38:21 +12:00
Jesse Hills
cc576cf1a9 Merge branch 'dev' into bump-2023.5.0b1 2023-05-11 09:38:20 +12:00
Jesse Hills
97a71482a9 Validate project details are set for dashboard_import (#4802) 2023-05-11 08:55:05 +12:00
Jesse Hills
8822b6c808 Make i2s_audio bclk_pin optional (#4801) 2023-05-11 07:17:59 +12:00
Jesse Hills
5099595aee Wrap VA code (#4800) 2023-05-10 16:46:32 +12:00
Jesse Hills
39a650ee54 Add more configuration for microphones - i2s/pdm/adc (#4775) 2023-05-10 16:37:21 +12:00
Jimmy Hedman
b19c7d462b Fixed calculation of start and end dhcp range (#4785) 2023-05-10 13:03:43 +12:00
Fabian
a8b821c213 [display] Small display print performance improvement (#4788) 2023-05-10 12:47:24 +12:00
Fabian
535003014b Keep Unit of Measurement in Flash. (#4719)
Co-authored-by: Your Name <you@example.com>
2023-05-10 11:42:55 +12:00
Jesse Hills
3c05ae4e1a Add more envs to root platformio (#4799) 2023-05-10 11:38:51 +12:00
Jesse Hills
c835b67bac Add host target platform (#4783)
Co-authored-by: Otto winter <otto@otto-winter.com>
2023-05-10 11:38:18 +12:00
Fabian
8c32941428 [ili9xxx] Improve fill operation performance (#4702)
Co-authored-by: Your Name <you@example.com>
2023-05-10 11:19:28 +12:00
Alfredo
b5dac00dcb Fix ezo parsing (#4792) 2023-05-10 11:16:14 +12:00
bouhaa
ffdc721c79 SM2135 Add optional current configuration, avoid communication failures. (#3850)
Co-authored-by: matika77 <xmaximx@gmx.net>
Co-authored-by: Dion <contact@dd32.id.au>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-05-10 11:06:26 +12:00
Jesse Hills
0828a9fc11 Bump ESP32-audioI2s to 2.0.7 (#4796) 2023-05-10 09:13:01 +12:00
Jesse Hills
4b664b6f09 Create esp32 rmt addressable light driver (#4708) 2023-05-09 09:33:43 +12:00
Jesse Hills
679633245d Add gp8403 output component (#4495)
Co-authored-by: Samuel Sieb <samuel-github@sieb.net>
2023-05-08 12:45:12 +12:00
Jesse Hills
ce8a77c765 Speaker support (#4743) 2023-05-08 10:36:17 +12:00
Jesse Hills
2f78c4acfa Merge pull request #4778 from esphome/bump-2023.4.4
2023.4.4
2023-05-04 11:31:40 +12:00
Jesse Hills
72f6841aac Bump version to 2023.4.4 2023-05-04 10:53:06 +12:00
Tim Niemueller
10bd9b14fc Fixes for Arduino 2.7.4 (for FastLED) (#4777) 2023-05-04 10:53:05 +12:00
Guillermo Ruffino
3498aade85 update schema gen to 2023.4.0 (#4772) 2023-05-04 10:18:45 +12:00
Chris Nussbaum
c4539e10fb Revert "Template sensors always publish on update interval (#2224)" (#4774) 2023-05-04 10:16:00 +12:00
Tim Niemueller
2b3052e9d7 Fixes for Arduino 2.7.4 (for FastLED) (#4777) 2023-05-04 10:13:30 +12:00
Jesse Hills
e725e15f7a Merge pull request #4769 from esphome/bump-2023.4.3
2023.4.3
2023-05-02 17:28:32 +12:00
Jesse Hills
4d1113e265 Bump version to 2023.4.3 2023-05-02 17:10:46 +12:00
Jesse Hills
52352ac27a Fix i2s media player on devices with no internal DAC (#4768) 2023-05-02 17:10:46 +12:00
Keith Burzinski
f60b2b754d Fix sprinkler switch restore_mode (#4756) 2023-05-02 17:10:46 +12:00
Jesse Hills
4a3f9712b2 Fix i2s media player on devices with no internal DAC (#4768) 2023-05-02 16:57:40 +12:00
dependabot[bot]
fb094fca0f Bump zeroconf from 0.56.0 to 0.60.0 (#4767)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-02 09:52:42 +12:00
looping40
de10b356cf Max6956 support added (#3764)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-05-02 09:51:48 +12:00
cooki35
bd6d6caa8a Add support for V2 of the waveshare 5.83in e-paper display. (#3660) 2023-05-02 09:36:20 +12:00
Mat931
1c4af08ed3 Add support for BLE passkey authentication (#4258)
Co-authored-by: Branden Cash <203336+ammmze@users.noreply.github.com>
2023-05-02 09:25:10 +12:00
Philippe FOUQUET
c97d361b6c Add support for hyt271 (#4282)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-05-01 16:18:31 +12:00
marshn
379b1d84dd RF Codec for Drayton Digistat heating controller (#4494) 2023-05-01 16:12:53 +12:00
Luis Andrade
c13e20643b play_folder bugfix and addition of play_mp3 (#4758) 2023-05-01 16:01:24 +12:00
Mat931
76b6fcf554 Add PCA6416A Support (#4681) 2023-05-01 16:00:21 +12:00
Jesse Hills
57e909e790 Only pre-install libraries in docker images (#4766) 2023-05-01 15:57:57 +12:00
dependabot[bot]
d6f7876e68 Bump pyupgrade from 3.3.1 to 3.3.2 (#4751)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-05-01 00:01:52 +00:00
Jesse Hills
56e0923c22 Switch ESPAsyncTCP-esphome to esphome fork (#4764) 2023-05-01 11:09:01 +12:00
tracestep
f4b98f5e32 Power down PN532 before deep sleep (#4707) 2023-05-01 09:24:15 +12:00
Jesse Hills
2d56b70a36 Bump git version in Dockerfile (#4763) 2023-05-01 08:51:46 +12:00
dependabot[bot]
980cfaf295 Bump aioesphomeapi from 13.7.1 to 13.7.2 (#4753)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-01 07:57:02 +12:00
Keith Burzinski
c2a43c733a Fix sprinkler switch restore_mode (#4756) 2023-05-01 07:52:05 +12:00
RoboMagus
568e65a6ab Fix assumed_state switch webserver (#4259) 2023-05-01 07:28:21 +12:00
Jesse Hills
59d6b3afa0 Merge branch 'release' into dev 2023-04-27 20:06:04 +12:00
Jesse Hills
b89c04b928 Merge pull request #4748 from esphome/bump-2023.4.2
2023.4.2
2023-04-27 20:02:15 +12:00
Jesse Hills
12090657bb Bump version to 2023.4.2 2023-04-27 19:36:21 +12:00
itpeters
4e21cf0bdd Don't allow fingerprint_grow enroll cancellation when no enrollment started (#4745) 2023-04-27 19:36:21 +12:00
Jesse Hills
ba4ef72d56 Only request VA port from first client that is subscribed (#4747) 2023-04-27 19:36:21 +12:00
Jimmy Hedman
f3e6a4314f Debug component doesn't work on RP2040 (#4728) 2023-04-27 19:36:21 +12:00
gcopeland
e14ce3d950 I2c scan recovery reset fix (#4724)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-27 19:36:21 +12:00
itpeters
70aa38f5bd Don't allow fingerprint_grow enroll cancellation when no enrollment started (#4745) 2023-04-27 16:34:20 +12:00
Jesse Hills
55ec082628 Only request VA port from first client that is subscribed (#4747) 2023-04-27 04:22:12 +00:00
Jesse Hills
6f27126c8d Move am43 sensor code and remove auto load on cover (#4631) 2023-04-27 13:24:42 +12:00
Jesse Hills
ee21a91313 Add mlx90614 sensors (#3749)
Co-authored-by: Greg Arnold <greg@arnoldassociates.com>
Co-authored-by: notsonominal <130870838+notsonominal@users.noreply.github.com>
2023-04-27 13:17:09 +12:00
Jesse Hills
c5efaa1c00 Remove climate legacy away flags (#4744) 2023-04-27 13:11:32 +12:00
Jesse Hills
6476357596 Expand the platformio dep installer to also install platforms and tools (#4716) 2023-04-27 12:26:06 +12:00
dependabot[bot]
77f71acbc8 Bump pytest from 7.3.0 to 7.3.1 (#4686)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-27 11:45:23 +12:00
dependabot[bot]
4a08a5413d Bump tornado from 6.2 to 6.3.1 (#4741) 2023-04-27 11:00:34 +12:00
dependabot[bot]
e3d89cc6b6 Bump pylint from 2.17.2 to 2.17.3 (#4740)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-27 10:49:40 +12:00
RoboMagus
64afb07e91 Fix 'blutooth' typo in esp32_ble component (#4738) 2023-04-27 10:48:53 +12:00
Keith Burzinski
f639f7c280 Add on_tag_removed trigger for RC522 (#4742) 2023-04-27 10:47:45 +12:00
Jimmy Hedman
986dd2ddd2 Debug component doesn't work on RP2040 (#4728) 2023-04-27 08:03:30 +12:00
gcopeland
7abdb5d046 I2c scan recovery reset fix (#4724)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-27 08:00:37 +12:00
Jesse Hills
0f1e186189 Merge pull request #4732 from esphome/bump-2023.4.1
2023.4.1
2023-04-24 09:47:08 +12:00
Jesse Hills
96d208e0d8 Bump version to 2023.4.1 2023-04-24 09:11:07 +12:00
Jesse Hills
38ed38864e Use proper schema for delta filter (#4723) 2023-04-24 09:11:07 +12:00
Samuel Sieb
a12ba7bd38 fix flip_x (#4727) 2023-04-24 09:11:06 +12:00
dependabot[bot]
4a177e3931 Bump aioesphomeapi from 13.7.0 to 13.7.1 (#4725)
Bumps [aioesphomeapi](https://github.com/esphome/aioesphomeapi) from 13.7.0 to 13.7.1.
- [Release notes](https://github.com/esphome/aioesphomeapi/releases)
- [Commits](https://github.com/esphome/aioesphomeapi/compare/v13.7.0...v13.7.1)

---
updated-dependencies:
- dependency-name: aioesphomeapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-23 20:53:50 +00:00
Alexander Momchilov
bef5b38d49 Add supports_stop trait to Cover (#3897)
* Add "stop" trait to Cover

* Add `supports_stop` to Cover protobuf msg

* Run `script/api_protobuf/api_protobuf.py`

... followed by `script/clang-format -i`

* Add `has_stop` field to template Cover

* Set `has_stop` during Cover codegen

* Set `supports_stop` trait on all other Cover types

* Bump APIVersion to 1.8

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-23 20:51:32 +00:00
Rebbe Pod
0a95f116fc Get Sunrise & Sunset for a Specific Date (#4712)
* Update real_time_clock.cpp

* Update real_time_clock.h

* Update sun.h

* Update sun.h

* Update sun.h

* Enable the sunAtLocation to be used externally

* Enable the sunAtLocation to be used externally

* Update sun.h

* Update sun.h

* update

* update

* update to only use one function

* Update sun.h

* Update sun.cpp
2023-04-23 20:44:35 +00:00
Jesse Hills
327cd662b4 Use proper schema for delta filter (#4723) 2023-04-23 20:42:46 +00:00
Samuel Sieb
bb05ba3d00 fix flip_x (#4727) 2023-04-22 07:41:12 +00:00
Keith Burzinski
c0ad5d1d16 Initial attempt at supporting ESP-IDF 5.0.0 (#4364)
* requirements: add pyparsing >= 3.0

ESP-IDF >= 5.0 requires pyparsing's rest_of_file, which was introduced
in version 3.0.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

* esp32: fix build with ESP-IDF >= 5

We need to include esp_timer.h to be able to use esp_timer_get_time().
This header existed in ESP-IDF < 5 so we don't need if guards.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

* ota: fix build with ESP-IDF >= 5

As of version 5, esp_task_wdt_init() takes a struct as argument. We also
need to include spi_flash_mmap.h.

[split unrelated change into separate commits, maintain ESP-IDF < 5
compat, use esp_task_wdt_reconfigure, add commit message]
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

* core: fix build with ESP-IDF >= 5

These header files already existed in ESP-IDF < 5 so skip if guards.

[add commit message]
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

* wifi: fix build with ESP-IDF >= 5

ESP-IDF 4.1 introduced the esp-netif API as successor to the tcp_adapter
API. The tcp_adapter API was removed in ESP-IDF 5.0.0. Part of the wifi
component was already migrated to the new API. Migrate the leftover uses
of the old API to the new API to fix build on ESP-IDF >= 5.

The version of ESP-IDF currently in use (4.4.4) supports the new API, so
we don't need any if guards to maintain backwards compatibility.

Also replace xQueueHandle, which is a pre FreeRTOS v8.0.0 data type,
with QueueHandle_t, so we don't need to enable backward compatibility
(CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY).

This reverts part of commit d42f35de5d to wifi_component_esp_idf.cpp,
as the esp-netif API handles that internally.

[replace pre FreeRTOS v8.0.0 data type, add commit message]
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

* mdns: fix build with ESP-IDF >= 5

In ESP-IDF 5.0.0, the mdns component was removed and moved to another
repository. Since the mdns component in esphome is always built, we
need to add the mdns component from the esp-protocols repository. This
component depends on ESP-IDF >= 5.0, so we need to add a version guard.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

* docker: install python3-venv

As of version 6.0.1, platform-espressif32 requires python3-venv.
Switching between esp-idf 4.4.4 and 5.0 causes problems with esp-idf
python dependencies installed by PlatformIO. They've solved this by
using venv. Install python3-venv so that platform-espressif32 6.0.1 and
later can be used, and we don't need to wipe the dependencies manually
when switching esp-idf versions.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>

---------

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Co-authored-by: Stijn Tintel <stijn@linux-ipv6.be>
2023-04-20 03:54:06 +00:00
Bella Coola
4c39631428 Add support for passive WiFi scanning (#4666)
* Add support for passive WiFi scanning.

* Apply suggestions from code review

Made changes suggested by @jesserockz

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

---------

Co-authored-by: BellaCoola <unknown>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-20 03:53:42 +00:00
Fabian
afc2b3b74f Keep Device Class in Flash. (#4639)
* Keep Device Class in Flash.

* Remove blank line

---------

Co-authored-by: Your Name <you@example.com>
2023-04-20 03:53:35 +00:00
Jesse Hills
19fc1417ae Merge pull request #4715 from esphome/bump-2023.4.0
2023.4.0
2023-04-20 15:18:09 +12:00
Jesse Hills
e2fefa51f5 Bump version to 2023.4.0 2023-04-20 14:06:53 +12:00
Jesse Hills
f668d5617f Merge branch 'beta' into bump-2023.4.0 2023-04-20 14:06:52 +12:00
Jesse Hills
47c4ff15d6 Merge pull request #4714 from esphome/bump-2023.4.0b4
2023.4.0b4
2023-04-20 14:00:12 +12:00
Jesse Hills
ccf1bdc0b4 Bump version to 2023.4.0b4 2023-04-20 13:10:26 +12:00
Jesse Hills
e993fcf80c Bump arduino platform version to 5.3.0 (#4713)
* Bump arduino platform version to 5.3.0

* Update root platformio.ini
2023-04-20 13:10:25 +12:00
tracestep
1bdc30a09e Add ethernet powerdown (fixes esphome/issues#4420) (#4706)
* Add ethernet powerdown

* Add on_shutdown (fixes esphome/issues#4420

* Sync dev and clang-tidy fix

* fix typo and trainling space

* Initialize phy_ member

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Use `this` pointer

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Member initialized at declaration

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Use `this` pointer

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Use `this` pointer

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-20 13:10:25 +12:00
Jesse Hills
0f7e34e7ec Bump arduino platform version to 5.3.0 (#4713)
* Bump arduino platform version to 5.3.0

* Update root platformio.ini
2023-04-20 00:44:49 +00:00
Jesse Hills
f56e89597f Merge pull request #4711 from esphome/bump-2023.4.0b3
2023.4.0b3
2023-04-20 11:14:00 +12:00
Jesse Hills
9460fb28c4 Bump version to 2023.4.0b3 2023-04-20 10:15:34 +12:00
Jesse Hills
7207b9734f Call on_error if no api client connected that handles voice (#4709) 2023-04-20 10:15:34 +12:00
tracestep
2be703b329 Add ethernet powerdown (fixes esphome/issues#4420) (#4706)
* Add ethernet powerdown

* Add on_shutdown (fixes esphome/issues#4420

* Sync dev and clang-tidy fix

* fix typo and trainling space

* Initialize phy_ member

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Use `this` pointer

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Member initialized at declaration

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Use `this` pointer

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Use `this` pointer

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-19 22:10:01 +00:00
Jesse Hills
4cea74ef3b Call on_error if no api client connected that handles voice (#4709) 2023-04-19 20:56:37 +00:00
Jesse Hills
3be3267d06 Merge pull request #4700 from esphome/bump-2023.4.0b2
2023.4.0b2
2023-04-17 17:16:16 +12:00
Jesse Hills
98db604dba Bump version to 2023.4.0b2 2023-04-17 15:45:35 +12:00
Jesse Hills
ebf6f8c6de Add event triggers to voice_assistant (#4699)
* Add event triggers to voice_assistant

* Add triggers to test
2023-04-17 15:45:34 +12:00
Szewcson
2ebacad398 Add timeout to i2c write error logs (#4697) 2023-04-17 15:45:34 +12:00
Jimmy Hedman
53c59cf675 Fixed dns2 for ethernet (#4698) 2023-04-17 15:45:34 +12:00
Jesse Hills
9da261cb39 debug component, allow without debug logging (#4685) 2023-04-17 15:45:34 +12:00
Jesse Hills
3a587ea0d4 Add event triggers to voice_assistant (#4699)
* Add event triggers to voice_assistant

* Add triggers to test
2023-04-17 02:57:28 +00:00
Szewcson
8a60919e1f Add timeout to i2c write error logs (#4697) 2023-04-16 20:12:13 +00:00
Jimmy Hedman
382dcddf12 Fixed dns2 for ethernet (#4698) 2023-04-16 20:10:07 +00:00
Jesse Hills
6b67acbeb5 debug component, allow without debug logging (#4685) 2023-04-14 02:29:28 +00:00
dependabot[bot]
7b0fca6824 Bump docker/build-push-action from 3 to 4 (#4367)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3 to 4.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-13 08:13:13 +00:00
dependabot[bot]
47555d314a Bump peter-evans/create-pull-request from 4 to 5 (#4661)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4 to 5.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v4...v5)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-13 08:12:24 +00:00
dependabot[bot]
0643b71908 Bump aioesphomeapi from 13.5.1 to 13.7.0 (#4676)
Bumps [aioesphomeapi](https://github.com/esphome/aioesphomeapi) from 13.5.1 to 13.7.0.
- [Release notes](https://github.com/esphome/aioesphomeapi/releases)
- [Commits](https://github.com/esphome/aioesphomeapi/compare/v13.5.1...v13.7.0)

---
updated-dependencies:
- dependency-name: aioesphomeapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-13 05:31:47 +00:00
kahrendt
afc848bf22 Add Bayesian type for binary_sensor_map component (#4640)
* initial support for Bayesian type

* Cast bool state of binary_sensor to uint64_t

* Rename channels to observations with Bayesian

* Improve/standardize comments for all types

* Use black to correct sensor.py formatting

* Add SUM and BAYESIAN binary sensor map tests

* Remove unused variable

* Update esphome/components/binary_sensor_map/binary_sensor_map.cpp

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-13 01:48:29 +00:00
Jesse Hills
9fbbcd6d8a Merge pull request #4683 from esphome/bump-2023.4.0b1
2023.4.0b1
2023-04-13 11:06:53 +12:00
Jesse Hills
cc1eb648f9 Only allow 5 jobs from each CI run to be in parallel (#4682) 2023-04-12 22:46:19 +00:00
Jesse Hills
04a139fe3d Bump version to 2023.5.0-dev 2023-04-13 10:13:53 +12:00
Jesse Hills
1a86167a47 Bump version to 2023.4.0b1 2023-04-13 10:13:52 +12:00
Jesse Hills
614ed7fd0c Merge branch 'dev' into bump-2023.4.0b1 2023-04-13 10:13:52 +12:00
spacemanspiff2007
4eb69d6af5 Fix restore (#4655)
* ALWAYS_OFF for fan

* ALWAYS_OFF for light

* ALWAYS_OFF for switch
2023-04-12 21:28:02 +00:00
Fabian
0547f2a931 Add KSZ8081 support. (#4668)
Co-authored-by: Your Name <you@example.com>
2023-04-12 21:22:08 +00:00
unhold
b5fbe0b145 Fix cut-off on 2.13" waveshare/ttgo epaper displays (#4255)
The controller of the 2.13" waveshare/ttgo epaper displays operates with a 128x250 buffer,
while only 122x250 pixels are shown. While this can be ignored for rotations 0/270°,
with roations 90/180°, 6 pixels are cut-off from the top or left edge.
This change introduces a distinction between object width and controller width,
resulting in pixel-perfect rotations.
2023-04-12 21:19:52 +00:00
unhold
443c3c2a56 Fix graph limits for negative values and other corner cases (#4253)
Fix lower graph limit for negative values by rounding down instead of truncating.
Consistently handle the corner cases: empty trace, min=max (e.g. single value)
by drawing the grid lines for a single grid division.
2023-04-12 21:18:09 +00:00
X-Ryl669
d75daa9644 Add always trigger stop (#4249)
* feat: Add manual control config override 1/3

* feat: Add manual control config override 2/3

* feat: Add manual control config override 3/3

* No magical number is better

Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>

---------

Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>
2023-04-12 21:16:44 +00:00
Joe
7963abb27a Fix BedJet setup priority [fixes esphome/issues#3807] (#4677)
There is a race condition where a BedJet unit previously had its BLE
"notify" flag enabled, and it continues to broadcast these notify
packets even after the ESP32 (and BLEClient) goes away, such as during
a crash or unplugging power.

BLEClient::setup_priority=AFTER_BLUETOOTH, while
BedJetHub::setup_priority=AFTER_WIFI. When the ESP32 starts back up
again, BLEClient::setup() happens first and will start receiving the
BLE notify packets almost immediately. Since we register the BLEClient
child from codegen, BedJetHub is registered as a child already by this
point, so BLEClient dispatches the notify status packet (and other gatt
events) to the BedJetHub handler, even though BedJetHub::setup() has
not been called yet.

We initialize BedJetHub::codec_ in setup(), so if BLEClient starts
dispatching gatt events before setup() is called, then codec_ will not
be initialized yet. This causes BedJetHub's gatt notify handler to call
`this->codec_->decode_notify()` on an uninitialized null pointer. Since
invoking a method does not have to dereference the pointer, that method
invocation is allowed; but later trying to access memory on that
instance results in a StoreProhibited panic.

Changing the BedJetHub's setup_priority to BLUETOOTH causes it to be
setup before BLEClient, so that by the time BLEClient starts to receive
BLE packets, BedJetHub is ready to receive them.
2023-04-12 08:33:15 +00:00
Jesse Hills
0b9e8fda34 Fix pin schema for i2s microphone (#4680) 2023-04-12 08:25:19 +00:00
Dave Johnston
a3cacc0c8b Add support for SSD1306 72x40 displays (#4659)
* add SSD1306 72x40

* fix indents

* fix clang style
2023-04-12 04:02:29 +00:00
Keith Burzinski
5a4840f641 Fix some NFC/PN532 crashes (#4678)
* Add + use some constants, fix some crashes

* Fix PN532 crashes
2023-04-12 02:29:06 +00:00
Keith Burzinski
3d7d689040 Fix ESP32 SPI hardware assignment in Arduino fw (#4669) 2023-04-12 01:38:41 +00:00
Jesse Hills
b60c08dd28 Add push to talk voice assistant (#4648)
* Add push to talk voice assistant

* Refactor most code into voice_assistant

* Make voice_assistant the component and remove push_to_talk (can be done in yaml)

* Fix component setup

* Always AF_INET to match serverside

* Fix microphone and media player co-existence

* Format

* Update codeowners

* Update test file

* Fix endifs

* nullptr not NULL

* clang-tidy

* Format

* fixup: Add VA event data

* Generate proto

* Parse and log events

* Add default to switch

* Fix

* Add mic/va to test5
2023-04-11 23:45:10 +00:00
dependabot[bot]
80bc567c31 Bump pytest from 7.2.2 to 7.3.0 (#4673)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.2 to 7.3.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.2...7.3.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 22:29:40 +00:00
dependabot[bot]
888ac2e180 Bump zeroconf from 0.47.4 to 0.56.0 (#4674)
Bumps [zeroconf](https://github.com/python-zeroconf/python-zeroconf) from 0.47.4 to 0.56.0.
- [Release notes](https://github.com/python-zeroconf/python-zeroconf/releases)
- [Changelog](https://github.com/python-zeroconf/python-zeroconf/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python-zeroconf/python-zeroconf/compare/0.47.4...0.56.0)

---
updated-dependencies:
- dependency-name: zeroconf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 22:29:22 +00:00
Jörg Thalheim
421ebcc8b2 use PRIx macros for printing u32/i32 ints (#4671)
This fix compilation issues with the latest esp-idf.
2023-04-10 22:20:02 +00:00
dependabot[bot]
b56fa8c50a Bump black from 23.1.0 to 23.3.0 (#4635)
* Bump black from 23.1.0 to 23.3.0

Bumps [black](https://github.com/psf/black) from 23.1.0 to 23.3.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/23.1.0...23.3.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update black in pre-commit

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-04 02:34:36 +00:00
Ben Hoff
42401775e1 Added in mmc5603 code (#4175)
* added in mmc5603 code

* added in codeowner

* fix linter errors

* whitespace linter errors

* added codeowner

* clang format

* remove clang format from python code

* fix whitespace

* add tests

* fix test

* make requested edits

* remove status manipulation

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-04 02:34:14 +00:00
dependabot[bot]
9c9bc58c16 Bump pylint from 2.16.4 to 2.17.2 (#4650)
* Bump pylint from 2.16.4 to 2.17.2

Bumps [pylint](https://github.com/PyCQA/pylint) from 2.16.4 to 2.17.2.
- [Release notes](https://github.com/PyCQA/pylint/releases)
- [Commits](https://github.com/PyCQA/pylint/compare/v2.16.4...v2.17.2)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add return 0 to run_miniterm

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-03 23:55:00 +00:00
tracestep
fbc129cccc Version retry (fixes esphome/issues#3823) (#4651) 2023-04-03 22:23:31 +00:00
Jesse Hills
99638190cb VSCode / devcontainer updates (#4647) 2023-04-03 19:44:46 +00:00
RoboMagus
d78e9e6aa8 Number step not optional (#4649)
* Number step not optional

* Update __init__.py

* Update __init__.py

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-04-03 19:31:11 +00:00
Mikkel Jeppesen
878155a03d Log calibration results at level INFO (#4240)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-31 09:05:28 +00:00
Fabian
9922eb83e2 Support advanced UART customization (#4465)
* Add methods to get hardware uart details.

* Fix `setRxBufferSize` error.

---------

Co-authored-by: Your Name <you@example.com>
2023-03-31 04:30:24 +00:00
Fabian
79f861f012 Avoid sensor padding. (#4638)
Co-authored-by: Your Name <you@example.com>
2023-03-31 04:29:17 +00:00
Fabian
4faa9d109e entity_base avoid padding bytes. (#4637)
Co-authored-by: Your Name <you@example.com>
2023-03-31 04:28:49 +00:00
kahrendt
28534ecc61 Binary map bugfixes (#4636)
* limit configuration to 64 binary sensors to match code limitation

* remove superfluous debug logging

* improve state publishing logic eliminating NAN being sent on boot in certain cases

* adjust type for bitmask shift to match mask variable type
2023-03-31 04:27:24 +00:00
felixlungu
616e0a21d8 add bluetooth mac address in dump_config() (#4628)
* add bluetooth mac address in dump_config()

* Update ble.cpp

* Update ble.cpp

* Update ble.cpp

* Update ble.cpp

* Update ble.cpp

* Update ble.cpp

* Update ble.cpp
2023-03-30 01:12:06 +00:00
Jesse Hills
a546ffd490 Add ifdef to new bt proxy unsubscribe (#4634)
* Add ifdef to new bt proxy unsubscribe

* Also add to subscribe message and wrap api conneciton code

* Format file
2023-03-30 01:08:51 +00:00
Jesse Hills
b5d0aede38 Remove AUTO_LOAD from as3935 (#4630) 2023-03-30 01:08:31 +00:00
github-actions[bot]
a014d853a4 Synchronise Device Classes from Home Assistant (#4633)
* Synchronise Device Classes from Home Assistant

* Remove count do the `DEVICE_CLASSES` list is also updated

* Format file

---------

Co-authored-by: esphomebot <esphome@nabucasa.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-29 02:47:00 +00:00
Jesse Hills
c4ddf7697d Update sync-device-classes.yml 2023-03-29 14:02:34 +13:00
Jesse Hills
a2931b6774 Add workflow to sync device classes with HA dev (#4629) 2023-03-28 23:31:07 +00:00
Fabian
3ac7bf3761 EntityBase: Move ObjectId to Flash (#4569)
* Move EntityBase Object Id from memory to flash.

* Sprinkler use common `setup_entity` method.

* Remove `EntityBase` from Sprinkler.

* Support for entity names set to None

* change so gh PR picks up commit.

---------

Co-authored-by: Your Name <you@example.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-28 09:00:34 +00:00
richardhopton
922344811f feat: Add support to unsubscribe from BLE advertisements (#4620)
* feat: Add support to unsubscribe from BLE advertisements

* Fix tests & clang

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-28 08:54:58 +00:00
Fabian
cb2fcaa9b1 EntityBase Name can stay in flash. (#4594)
* `EntityBase`can stay in flash.

* Trying to please the CI.

---------

Co-authored-by: Your Name <you@example.com>
2023-03-28 06:38:56 +00:00
Alfredo
1f50bd0649 Fix EzoCommandType enum (#4593)
* Fix EzoCommandType enum

Assign explicit value to EZO_CALIBRATION, and rescale all subsequent values.

* Remove enum values

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-27 22:08:26 +00:00
Jesse Hills
e4b2de5c68 Merge pull request #4623 from esphome/bump-2023.3.2
2023.3.2
2023-03-27 16:45:14 +13:00
Jesse Hills
f862b479e7 Bump version to 2023.3.2 2023-03-27 15:58:29 +13:00
tracestep
358c59bd8d SX1509 minimum loop period (fixes esphome/issues#4325) (#4613)
* Minimum loop period (fixes esphome/issues#4325)

* clang-tidy suggestions

* More clang-tidy suggestions
2023-03-27 15:58:28 +13:00
guillempages
74fe135c9c Fix animation resizing (#4608)
Animation resizing in RGB24 format is causing an error "Image cannot be resized to a bigger size". Other image types do not show the issue, and the only difference is the "image.thumbnail" call.

Removed the call and tested; the animation is shown with the desired size.
2023-03-27 15:58:28 +13:00
Jesse Hills
8d3896172d Swap curly brackets for round on LockGuard (#4610) 2023-03-27 15:58:28 +13:00
Kai Gerken
9d9725144d Fix compile error on pzemdc.h (#4583) 2023-03-27 15:58:28 +13:00
Jesse Hills
dd8dc1ef1d Merge pull request #4609 from esphome/bump-2023.3.1
2023.3.1
2023-03-22 12:40:28 +13:00
Jesse Hills
bc427de16a Bump version to 2023.3.1 2023-03-22 12:03:34 +13:00
Jesse Hills
db5988bbe1 rp2040: Use fake Mutex lock (#4602) 2023-03-22 12:03:34 +13:00
Nathaniel Wesley Filardo
a3875af4b4 climate: brown paper bag fix for on_configure (#4573)
I forgot this hunk in https://github.com/esphome/esphome/pull/4511 .
I'm sorry for the noise.
2023-03-22 12:03:34 +13:00
Jesse Hills
e6737479f7 Merge pull request #4568 from esphome/bump-2023.3.0
2023.3.0
2023-03-16 10:40:18 +13:00
Jesse Hills
7f75832bf1 Bump version to 2023.3.0 2023-03-16 09:38:19 +13:00
Jesse Hills
33339e3bd8 Merge branch 'beta' into bump-2023.3.0 2023-03-16 09:38:19 +13:00
Jesse Hills
c298c1166f Merge pull request #4567 from esphome/bump-2023.3.0b6
2023.3.0b6
2023-03-16 09:34:00 +13:00
Jesse Hills
c3d9eef01f Bump version to 2023.3.0b6 2023-03-16 08:57:54 +13:00
NP v/d Spek
5ffdc66864 fixing shrink and extend functions of the displaybuffer's Rect class (#4565)
* fixing rectangle's `shrink` and `extend`

* fixed the rect::shrink and rect::inside methods
and added rect:equal() method

* fixed internal clang issue again. When would is
this going to be fixed :(

* fixed internal clang issue again. When would is
this going to be fixed :(

* remove trailing space
2023-03-16 08:57:54 +13:00
Jesse Hills
9922c1503a Merge pull request #4564 from esphome/bump-2023.3.0b5
2023.3.0b5
2023-03-15 23:46:14 +13:00
Jesse Hills
fce99d4b17 Bump version to 2023.3.0b5 2023-03-15 21:20:08 +13:00
Jesse Hills
11567085d8 Mark esp32_touch supported only on standard esp32 variant (#4562)
* Mark esp32_touch supported only on standard esp32 variant

* Add back default
2023-03-15 21:20:08 +13:00
Keith Burzinski
83f8e84247 Remove switch actions during config; bump setup priority (#4563) 2023-03-15 21:20:08 +13:00
Jesse Hills
11eb5cb0fa Merge pull request #4559 from esphome/bump-2023.3.0b4
2023.3.0b4
2023-03-14 16:17:51 +13:00
Jesse Hills
9a7af97b2d Bump version to 2023.3.0b4 2023-03-14 14:11:55 +13:00
Stroe Andrei Catalin
5e11469f50 Added response for Tuya RSSI command (#4549)
* Added wifi rssi util
Added tuya mcu response to wifi rssi command

* Cleanup

* PR Comments

* PR Comments
2023-03-14 14:11:55 +13:00
DAVe3283
0c7a3d1fff Revert "Remove state class from uptime sensor (#4345)" (#4557)
This reverts commit 36c2e770bf.
Addresses esphome/issues#4193.
2023-03-14 14:11:55 +13:00
Eduardo Roldan
8a705bf4b0 pipsolar component. Correct the sscanf format for QPIG command parsing to set pv_input_voltage as float (not int) (#4165) 2023-03-14 14:11:55 +13:00
Jesse Hills
6a89180deb Merge pull request #4553 from esphome/bump-2023.3.0b3
2023.3.0b3
2023-03-13 15:31:04 +13:00
Jesse Hills
65d2b806cc Bump version to 2023.3.0b3 2023-03-13 13:32:21 +13:00
Jesse Hills
c149a3033c Map gpio pins for touch on esp32-s2/s3 (#4552)
* Map gpio pins for touch on esp32-s2/s3

* fix value
2023-03-13 13:32:21 +13:00
NP v/d Spek
4b7c233f1a On the ILI9xxx display's enable the psram on esp32 and allow big screen (#4551)
* enable the psram on esp32 and allow big screen

* update CODEOWNERS

* small update

* update CODEOWNERS again.

* Removed the M5STACK because it is a ESP32 device.

* i removed the wrong model

* update the error message.
2023-03-13 13:32:21 +13:00
Jesse Hills
6e8e9c2aa9 Allow AUTO_LOAD to be a function (#4550) 2023-03-13 13:32:21 +13:00
Dorian Zedler
b6f628ee40 Feat: add support for hex color in color component (#4493)
* Feat: add support for hex color in color component

* Chore: move hex color validator to color component

* Chore: add test

* Chore: fix formatting

* Chore: make linter happy

* Chore: make linter happy

* Fix: parse correct offsets

Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>

* Chore: use cv.Invalid

* Fix: remove # because it indicates a comment in yaml

* Fix: only allow hex if no other color value is set

* Fix: tests

* Fix: mutual exclusion of raw and hex colors

* Chore: format file

* Update __init__.py

---------

Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-13 13:32:21 +13:00
Martin Murray
bf79a700b7 Add carbon dioxide device class to scd30 sensor schema. (#4547) 2023-03-13 13:32:21 +13:00
jakehdk
cdeb6e750f Add support for new clones of mpu6050 responding with 0x70 address (#4546)
Co-authored-by: jakehdk <Jake@Jakobs-MacBook-Pro.local>
2023-03-13 13:32:21 +13:00
Jesse Hills
dd226360bb Merge pull request #4542 from esphome/bump-2023.3.0b2
2023.3.0b2
2023-03-09 19:03:39 +13:00
Jesse Hills
1a9aedf152 Bump version to 2023.3.0b2 2023-03-09 15:47:57 +13:00
Carlos Garcia Saura
d82c6df57e Correct BME680 gas calculation and heater_off (#4498)
* Fix missing data array

* Fix incorrect bit offset

* Correct variable types

* Do same conversions as in original library

* Correct clang-format

* Move out float conversion for clarity

* Added check for heater stability

* Correct clang format

* Allow reporting gas resistance when heater is disabled

* Correct clang format

* Better error reporting by @DAVe3283

* Correct signed operation, range switching error was positive all the time
2023-03-09 15:47:57 +13:00
Oxan van Leeuwen
7c91b4474a Revert storing Font glyphs in manually-allocated memory (#4516)
This partially reverts commit 62459a8ae1.
2023-03-09 15:47:57 +13:00
Oxan van Leeuwen
a4f21db272 Drop broken logging macros (#4534) 2023-03-09 15:47:57 +13:00
NP v/d Spek
58a8e1859e Renaming and extending the ili9341 to the ili9xxx component (#4275)
* - Removed cleaning the screen twice.
  \Should be handled by  `DisplayBuffer::init_internal_();`
- Made ili9341::initalize() protected and renamed
  \ it to ili9341::initalize().
- ili9341::initalize() should only init the display
  \ and set the width and heigth.

* removed to much

* clang format fixes

* removing trailing underscors for
protected virtual methods

* removed the "override"  on display()

* clang fixes

* restored old changes

* Renamed the ili9341 platform to ili9xxx and added
multiple drivers as well. including PR #3848

* fixed most of the clang reported issues

* fixed reported issues

* last fixes

* Setting the right codeowners

* missing changes

* fixed naming Display() method.

* clang again

* clang fix

* fixes reported by @jesserockz & @gpambrozio

* a change to display.py removing an unneeded var

* re-introduce **backlight** option.

* update the ili9488 initialization

* update the ili9488 initialization and fix typo

* fixed typo

* add missing constants

* swap height and width back for the ili9488

* init fixes ili9488

* fixed lint issue
testing the init code

* oeps

* init fixes ili9488

* fixed wrong define

* fixed wrong define again

* removed some spaces

* revert to ili9341

* Remove parts that where used for
the switchplate

* lint fixes and removing unused function

* fix error and introducing 16bit color option

* fix error and introducing 16bit color option

* fix clang issue

* clang fix

* clang issue again

* is this what clang exprect

* clang fix

* clang fix

* try again

* let try again

* and again

* and the last clang fix

* remove the need of wifi

* update dimentions

* update ili8488 init code.

* update dimentions

* allow to change height and width

* dump color mode config

* fix

* fix

* modify logging

* referd back unrelated change

* code formatting commit and moving functions around

* add missing ;

* update code

* update code

* use the correct write_array for sending uint16_t

* fix panic loop

* fix panic loop

* - update the test file
- fixed sending display data

* clang fixes

* clang fixes

* clang fixes again

* remove .gitignore items

* remove .gitignore items

* make sure Update() can can not be called while
called

* clang correction

* adding a test yaml for the ili9341

* Update ili9341 example

* Make test ili9xxx/tests only local

* restore back old ili9341 driver code

* Add a new config for the M5Core

* fix clang request

* reverd to restore of the old ili9341
there is no proper way to say it is depricated.

* Remove the backlight/led pin from the config.
You need to use a proper light platform component

* Ili9488init changes (#88)

Fixed ILI9488 init settings, and adjusted pixel handling code to push pixels in 18 bit format.
This does not change the internal 16-bit representation.

* fixed some leftover clang issues from the merge.

* fixed the slang-tidy request.

* remove `backlight_pin` warning.

---------

Co-authored-by: JD Steffen <jdsteffen81@gmail.com>
2023-03-09 15:47:57 +13:00
Russell Cloran
2bed5b18c1 Add ESP32-S3 support in NeoPixelBus component (#4114)
* Add ESP32-S3 support in NeoPixelBus component

* Update NeoPixelBus version in platformio.ini
2023-03-09 15:47:57 +13:00
Jared Sanson
fb5eb57345 Fix ethernet clk_mode for GPIO0_OUT (#4307)
* Fix GPIO0_OUT definition for ethernet component

* Formatting

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-03-09 15:47:57 +13:00
Jesse Hills
63db42a1d4 Merge pull request #4536 from esphome/bump-2023.3.0b1
2023.3.0b1
2023-03-09 10:43:40 +13:00
Jesse Hills
f58ffe41f8 Bump version to 2023.3.0b1 2023-03-09 09:09:39 +13:00
Jesse Hills
445d2e372c Merge branch 'dev' into bump-2023.3.0b1 2023-03-09 09:09:39 +13:00
Jesse Hills
c037e95861 Merge pull request #4478 from esphome/bump-2023.2.4
2023.2.4
2023-02-23 14:17:01 +13:00
Jesse Hills
2e1b35959f Bump version to 2023.2.4 2023-02-23 13:42:02 +13:00
Jesse Hills
7f46d9e0f9 Fix multiple remote_receivers with triggers (#4477) 2023-02-23 13:42:01 +13:00
Samuel Sieb
069b5f81a0 fix parity (#4476)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2023-02-23 13:42:01 +13:00
konsulten
3a36d0b13f BL0939 state_class set for energy sensors (#4463)
BL0939 was missing TOTAL_INCREASING for energy (kWh) thus it did not show as statistics in home assistant
2023-02-23 13:42:01 +13:00
Jesse Hills
f0760e99b7 Merge pull request #4466 from esphome/bump-2023.2.3
2023.2.3
2023-02-20 08:54:32 +13:00
Jesse Hills
18fecf8c09 Bump version to 2023.2.3 2023-02-20 08:16:47 +13:00
Jesse Hills
414cf1b333 Update Manifest to rmeove unused dashboard files and include .c ethernet drivers (#4459) 2023-02-20 08:16:46 +13:00
jmichiel
d10f891f51 fix preset discovery config (#4451)
Co-authored-by: Michiel, Jeroen <jeroen.michiel@teledyneflir.com>
2023-02-20 08:16:46 +13:00
Jesse Hills
b5927322e6 Merge pull request #4458 from esphome/bump-2023.2.2
2023.2.2
2023-02-17 19:38:01 +13:00
Jesse Hills
1cf4107e1c Bump version to 2023.2.2 2023-02-17 19:11:15 +13:00
Jesse Hills
c12408326c Fix adoption of variants and pico-w (#4455) 2023-02-17 19:11:14 +13:00
Jesse Hills
4434e59e5a Merge pull request #4445 from esphome/bump-2023.2.1
2023.2.1
2023-02-16 15:44:32 +13:00
Jesse Hills
45180d98f6 Bump version to 2023.2.1 2023-02-16 14:06:42 +13:00
Jesse Hills
44494ad18e Add ESPHome version to generated platformio.ini (#4443)
* Add ESPHome version to generated platformio.ini

* Move description to platformio section
2023-02-16 14:06:42 +13:00
Jesse Hills
1447536906 Merge pull request #4441 from esphome/bump-2023.2.0
2023.2.0
2023-02-15 22:33:31 +13:00
Jesse Hills
27ec517084 Remove dup line 2023-02-15 21:39:17 +13:00
Jesse Hills
ce1f034bac Bump version to 2023.2.0 2023-02-15 19:29:02 +13:00
Jesse Hills
f1f96f16e9 Merge branch 'beta' into bump-2023.2.0 2023-02-15 19:29:02 +13:00
Jesse Hills
7665e9b076 Merge pull request #4433 from esphome/bump-2023.2.0b5
2023.2.0b5
2023-02-14 14:51:00 +13:00
Jesse Hills
227d94f38d Bump version to 2023.2.0b5 2023-02-14 13:59:49 +13:00
Sergey Dudanov
b724ae9e0e Fix setting wrong traits on midea climate component (#4425)
* Fix issue3914

* Remove also default presets and modes

* Fix traits after autoconf
2023-02-14 13:59:49 +13:00
Jesse Hills
df6cc14201 Bump esphome-dashboard to 20230214.0 (#4431) 2023-02-14 13:59:49 +13:00
Jesse Hills
d981d7859d Handle uart.write in json-config endpoint (#4430) 2023-02-14 13:59:49 +13:00
Jesse Hills
0f1ec515c1 Add version api endpoint (#4429) 2023-02-14 13:59:49 +13:00
WitchKing
78e18256f7 Ledc fix (#4338) 2023-02-14 13:59:49 +13:00
Jesse Hills
4899dfe642 Merge pull request #4423 from esphome/bump-2023.2.0b4
2023.2.0b4
2023-02-13 15:17:05 +13:00
Jesse Hills
d6b6e94059 Bump version to 2023.2.0b4 2023-02-13 11:54:27 +13:00
NP v/d Spek
310355a00b Fix check for empty clipping array (#4421) 2023-02-13 11:54:26 +13:00
NP v/d Spek
8cf26d6f3c Add Clipping to displaybuffer (#4271)
* adding Clipping support to the displaybuffer
- add rect structure

* removed unused define

* add missing property for storing the clipped areas

* include log header

* Move Rect method's code to cpp file
- removed obsolete remarks

* fixed reported issues

* make Rect class methods public

* clang fix

* Remove commented code

* Renaming clipping methods

* Multiple changes:
- replaced 32766 with VALUE_NO_SET
- fixed the way *_clipping(left, top, right, bottom) is stored
- add `is_clipping();`
- make sure that all clipped region are closed after `do_update_()`
- rename de parameters for `Rect::expand();`

* remove unneeded space

* replace define with static const uint8_t

* correcting my copy paste mistake

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-02-13 11:54:26 +13:00
Patrick Collins
b15a10f905 Climate PID Autotune Logging fixes (#4136)
* pid autotune logging fixes

* fixed clang-format request

* improved and clarified logging

* changed logging not to alter the TAG

* logging now does not alter TAG. fixed clang formattting

* fixed string issues

* playing with strings to please the clang gods

* playing with strings

* Delete secrets.yaml

* Delete console-fan-autotune-test.yaml

* Update esphome/components/pid/pid_autotuner.cpp

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Update esphome/components/pid/pid_autotuner.cpp

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Update esphome/components/pid/pid_autotuner.cpp

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Update esphome/components/pid/pid_autotuner.cpp

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

* Update esphome/components/pid/pid_autotuner.cpp

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-02-13 11:54:26 +13:00
Jesse Hills
5dcf1debd7 Merge pull request #4406 from esphome/bump-2023.2.0b3
2023.2.0b3
2023-02-09 18:04:35 +13:00
Jesse Hills
9b57e1ac1d Bump version to 2023.2.0b3 2023-02-09 17:38:54 +13:00
Jesse Hills
68683e3a50 Fix release workflow (#4405) 2023-02-09 17:38:54 +13:00
Jesse Hills
d83324c4dc Merge pull request #4404 from esphome/bump-2023.2.0b2
2023.2.0b2
2023-02-09 16:55:48 +13:00
Jesse Hills
ecde4c1d2d Bump version to 2023.2.0b2 2023-02-09 16:27:25 +13:00
Jesse Hills
bd8e470726 Bump curl version in docker (#4403) 2023-02-09 16:27:24 +13:00
Jesse Hills
d2913fe627 Merge pull request #4402 from esphome/bump-2023.2.0b1
2023.2.0b1
2023-02-09 15:59:06 +13:00
Jesse Hills
43acc7dc2c Bump version to 2023.2.0b1 2023-02-09 15:33:02 +13:00
Jesse Hills
e2a16d758b Merge branch 'dev' into bump-2023.2.0b1 2023-02-09 15:33:01 +13:00
Jesse Hills
4af4649e23 Merge pull request #4355 from esphome/bump-2022.12.8
2022.12.8
2023-01-27 10:04:29 +13:00
Jesse Hills
8bcddef39d Bump version to 2022.12.8 2023-01-27 09:44:41 +13:00
Franck Nijhof
4ac96ccea2 Add Home Assistant integration discovery (#4328) 2023-01-27 09:44:41 +13:00
Franck Nijhof
3c5de77ae9 Refactor NGINX configuration of Home Assistant Add-on (#4312) 2023-01-27 09:44:41 +13:00
Franck Nijhof
a2925b1d37 Migrate old-style S6 scripts to s6-rc.d (#4311) 2023-01-27 09:44:41 +13:00
Franck Nijhof
73748e9e20 Upgrades add-on base image to 6.2.0 (#4310) 2023-01-27 09:44:40 +13:00
Jesse Hills
75c9823899 Merge pull request #4350 from esphome/bump-2022.12.7
2022.12.7
2023-01-26 15:50:03 +13:00
Jesse Hills
c8c0bd3351 Bump version to 2022.12.7 2023-01-26 15:00:18 +13:00
melyux
e1cdeb7c8f Add a soft reset in setup() for bmp280 (#4329)
fixes https://github.com/esphome/issues/issues/3383
2023-01-26 15:00:17 +13:00
Alex
7f97f42552 Fix BME280 initialization before wifi setup (#4190)
fixes https://github.com/esphome/issues/issues/3530
2023-01-26 15:00:17 +13:00
Stephan Martin
aa7f3569ec rename esp32 CAN to TWAI, so it compiles again (#4334)
fixes https://github.com/esphome/issues/issues/4023
2023-01-26 15:00:17 +13:00
Denis Bodor (aka Lefinnois)
2d0a08442e fix stepper jump back with small steps (#4339) 2023-01-26 15:00:17 +13:00
Joakim Sørensen
d2380756b2 Add "content" to deploy-ha-addon-repo dispatch (#4349) 2023-01-26 15:00:17 +13:00
Jesse Hills
925e3cb6c9 Fix missing s 2023-01-23 20:34:31 +00:00
Jesse Hills
6757acba56 Merge pull request #4342 from esphome/bump-2022.12.6
2022.12.6
2023-01-24 08:58:45 +13:00
Jesse Hills
5cc91cdd95 Bump version to 2022.12.6 2023-01-24 08:30:42 +13:00
Jesse Hills
2b41886819 Move from docker manifest command to buildx with platforms (#4320) 2023-01-24 08:30:42 +13:00
Jesse Hills
72c6efd6a0 Merge pull request #4335 from esphome/bump-2022.12.5
2022.12.5
2023-01-23 09:27:18 +13:00
Jesse Hills
a1f1804112 Bump version to 2022.12.5 2023-01-23 09:06:20 +13:00
Jesse Hills
a8b1ceb4e9 Bump nano version in lint docker image (#4218) 2023-01-23 09:06:20 +13:00
Jesse Hills
4fb0f7f8c6 Merge pull request #4323 from esphome/bump-2022.12.4
2022.12.4
2023-01-21 16:17:57 +13:00
Jesse Hills
958cadeca8 Bump version to 2022.12.4 2023-01-20 18:33:09 +13:00
J. Nick Koston
00f2655f1a Always send the MTU request for BLE v3 cached connections (#4322)
closes https://github.com/esphome/esphome/pull/4321
fixes https://github.com/esphome/issues/issues/4041
fixes https://github.com/esphome/issues/issues/3951
2023-01-20 18:33:09 +13:00
Jesse Hills
074f5029eb Fix gpio pin mode for ISR pins (#4216) 2023-01-20 18:33:09 +13:00
Jesse Hills
1691976587 Merge pull request #4214 from esphome/bump-2022.12.3
2022.12.3
2022-12-20 23:34:01 +13:00
Jesse Hills
60e6b4d21e Bump version to 2022.12.3 2022-12-20 23:15:39 +13:00
Jesse Hills
5750591df2 Fix ESP32 GPIO when using INPUT PULLUP mode (#4213) 2022-12-20 23:15:39 +13:00
Jesse Hills
a75da54455 Merge pull request #4212 from esphome/bump-2022.12.2
2022.12.2
2022-12-20 11:06:34 +13:00
Jesse Hills
de7f6c3f5f Bump version to 2022.12.2 2022-12-20 10:49:36 +13:00
J. Nick Koston
4245480656 Handle zero padding anywhere in the combined adv data (#4208)
fixes https://github.com/esphome/issues/issues/3913
2022-12-20 10:49:35 +13:00
Jesse Hills
1824c8131e Fix import_full_config for adoption configs (#4197)
* Fix git raw url

* Fix setting full config query param

* Force dashboard import urls to have a branch or tag reference for full import
2022-12-20 10:49:35 +13:00
Jesse Hills
4e9606d2e0 Merge pull request #4196 from esphome/bump-2022.12.1
2022.12.1
2022-12-16 14:05:24 +13:00
Jesse Hills
78500fa933 Bump version to 2022.12.1 2022-12-16 13:36:11 +13:00
Jesse Hills
9c69b98a49 Fix i2s_audio media_player compiling for esp32-s2 (#4195) 2022-12-16 13:36:10 +13:00
Jesse Hills
e6d8ef98d3 Mark ESP32-S2 as not having Bluetooth (#4194) 2022-12-16 13:36:10 +13:00
Stefan Agner
3f1af1690b Support non-multiarch toolchains on 32-bit ARM (#4191)
fixes https://github.com/esphome/issues/issues/3904
2022-12-16 13:36:10 +13:00
Jesse Hills
84374b6b1e Merge pull request #4186 from esphome/bump-2022.12.0
2022.12.0
2022-12-14 17:06:24 +13:00
Jesse Hills
391316c9b5 Bump version to 2022.12.0 2022-12-14 16:37:39 +13:00
Jesse Hills
705c62ebd7 Merge branch 'beta' into bump-2022.12.0 2022-12-14 16:37:39 +13:00
Jesse Hills
cb520c00a5 Merge pull request #4185 from esphome/bump-2022.12.0b6
2022.12.0b6
2022-12-14 12:24:25 +13:00
Jesse Hills
2f24138345 Bump version to 2022.12.0b6 2022-12-14 12:03:03 +13:00
Jesse Hills
96512b80cc Revert camera config change for esp-idf (#4182) 2022-12-14 12:03:03 +13:00
Jesse Hills
fcb9b51978 Remove warnings when falling through switch cases on purpose (#4181) 2022-12-14 12:03:03 +13:00
Jesse Hills
f408f1a368 Merge pull request #4180 from esphome/bump-2022.12.0b5
2022.12.0b5
2022-12-13 19:42:18 +13:00
Jesse Hills
7d8d563c62 Bump version to 2022.12.0b5 2022-12-13 13:58:44 +13:00
J. Nick Koston
0a1f705fda Speed up bluetooth proxy connections when using esp-idf (#4171) 2022-12-13 13:58:44 +13:00
Jesse Hills
1952c1880b Remove internal pin restriction from cd74hc4067 (#4179) 2022-12-13 13:58:44 +13:00
Jesse Hills
b03967dac1 Merge pull request #4178 from esphome/bump-2022.12.0b4
2022.12.0b4
2022-12-13 10:14:08 +13:00
Jesse Hills
bcae2596a6 Bump version to 2022.12.0b4 2022-12-13 09:13:28 +13:00
Jesse Hills
fc0347c86c Bump esphome-dashboard to 20221213.0 (#4176) 2022-12-13 09:13:28 +13:00
Jesse Hills
d9563d4de1 Merge pull request #4174 from esphome/bump-2022.12.0b3
2022.12.0b3
2022-12-12 17:31:44 +13:00
Jesse Hills
cc7e2bf8db Bump version to 2022.12.0b3 2022-12-12 17:19:12 +13:00
Jesse Hills
5d98e2923b Increase watchdog timeout when starting OTA (#4172) 2022-12-12 17:19:12 +13:00
Jesse Hills
07197d12f6 Merge pull request #4163 from esphome/bump-2022.12.0b2
2022.12.0b2
2022-12-08 14:04:20 +13:00
Jesse Hills
7b0a298497 Bump version to 2022.12.0b2 2022-12-08 13:42:25 +13:00
Jesse Hills
21679cf2ba Fix ble parsing with zero padded advertisements (#4162) 2022-12-08 13:42:24 +13:00
Jesse Hills
4be7cd12a1 Merge pull request #4157 from esphome/bump-2022.12.0b1
2022.12.0b1
2022-12-07 17:25:12 +13:00
Jesse Hills
dee4d0ccb7 Bump version to 2022.12.0b1 2022-12-07 17:00:10 +13:00
Jesse Hills
7209dd8bae Merge pull request #4152 from esphome/bump-2022.11.5
2022.11.5
2022-12-06 13:12:57 +13:00
Jesse Hills
ab736c89bb Bump version to 2022.11.5 2022-12-06 12:52:48 +13:00
Jesse Hills
6911639617 Fix board pin alias lookup (#4147) 2022-12-06 12:52:48 +13:00
Jesse Hills
b9720d0715 Merge pull request #4130 from esphome/bump-2022.11.4
2022.11.4
2022-12-01 15:38:52 +13:00
Jesse Hills
47b3267ed4 Bump version to 2022.11.4 2022-12-01 13:47:50 +13:00
Jesse Hills
e16ba2adb5 Fix queuing scripts not compiling (#4077) 2022-12-01 13:47:50 +13:00
Nicolas Graziano
0a19b1e32c Dashboard, after login use relative url. (#4103) 2022-12-01 13:47:49 +13:00
Jesse Hills
bae9a950c0 current-based cover fix copy paste mistake (#4124) 2022-12-01 13:47:49 +13:00
Jesse Hills
72b2943332 Merge pull request #4083 from esphome/bump-2022.11.3
2022.11.3
2022-11-25 07:23:08 +13:00
Jesse Hills
4ec0ef7548 Bump version to 2022.11.3 2022-11-24 17:01:52 +13:00
Jesse Hills
25bc6761f6 Don't convert climate temperature step (#4082) 2022-11-24 17:01:52 +13:00
Brian Kaufman
81b6562c25 Fix units for refresh: never (#4048) 2022-11-24 17:01:52 +13:00
Samuel Sieb
ae74189fc2 fix missing library (#4051) 2022-11-24 17:01:51 +13:00
Jesse Hills
9e516efe10 Merge pull request #4074 from esphome/bump-2022.11.2
2022.11.2
2022-11-23 16:06:34 +13:00
Jesse Hills
366e29439e Bump version to 2022.11.2 2022-11-23 13:04:21 +13:00
J. Nick Koston
1c9c700d7f Avoid creating a new espbt::ESPBTUUID each loop when registering for notify (#4069) 2022-11-23 13:04:21 +13:00
J. Nick Koston
b2e6b9d31f Avoid 128bit uuid loop for 16/32 bit uuids (#4068) 2022-11-23 13:04:21 +13:00
Jesse Hills
7623f63846 rp2040_pwm frequency is per pair of pins (#4061) 2022-11-23 13:04:21 +13:00
Jesse Hills
2bfaf9dce3 Update web_server index (#4060) 2022-11-23 13:04:20 +13:00
Jesse Hills
5c2c1560bb Fix rp2040 pwm to use pico-sdk, not mbed (#4059) 2022-11-23 13:04:20 +13:00
Jesse Hills
f7096ab78e Merge pull request #4041 from esphome/bump-2022.11.1
2022.11.1
2022-11-17 15:40:51 +13:00
Jesse Hills
98f8feb625 Bump version to 2022.11.1 2022-11-17 13:52:15 +13:00
Jesse Hills
9944ca414e Support ADC on RP2040 (#4040) 2022-11-17 13:52:15 +13:00
283 changed files with 8024 additions and 1236 deletions

View File

@@ -4,53 +4,60 @@
"postCreateCommand": [
"script/devcontainer-post-create"
],
"containerEnv": {
"DEVCONTAINER": "1"
},
"runArgs": [
"--privileged",
"-e",
"ESPHOME_DASHBOARD_USE_PING=1"
],
"appPort": 6052,
"extensions": [
// python
"ms-python.python",
"visualstudioexptteam.vscodeintellicode",
// yaml
"redhat.vscode-yaml",
// cpp
"ms-vscode.cpptools",
// editorconfig
"editorconfig.editorconfig",
],
"settings": {
"python.languageServer": "Pylance",
"python.pythonPath": "/usr/bin/python3",
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"python.formatting.provider": "black",
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true,
"terminal.integrated.defaultProfile.linux": "bash",
"yaml.customTags": [
"!secret scalar",
"!lambda scalar",
"!include_dir_named scalar",
"!include_dir_list scalar",
"!include_dir_merge_list scalar",
"!include_dir_merge_named scalar"
],
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/*.pyc": {
"when": "$(basename).py"
},
"**/__pycache__": true
},
"files.associations": {
"**/.vscode/*.json": "jsonc"
},
"C_Cpp.clang_format_path": "/usr/bin/clang-format-13",
"customizations": {
"vscode": {
"extensions": [
// python
"ms-python.python",
"visualstudioexptteam.vscodeintellicode",
// yaml
"redhat.vscode-yaml",
// cpp
"ms-vscode.cpptools",
// editorconfig
"editorconfig.editorconfig",
],
"settings": {
"python.languageServer": "Pylance",
"python.pythonPath": "/usr/bin/python3",
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"python.formatting.provider": "black",
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true,
"terminal.integrated.defaultProfile.linux": "bash",
"yaml.customTags": [
"!secret scalar",
"!lambda scalar",
"!include_dir_named scalar",
"!include_dir_list scalar",
"!include_dir_merge_list scalar",
"!include_dir_merge_named scalar"
],
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/*.pyc": {
"when": "$(basename).py"
},
"**/__pycache__": true
},
"files.associations": {
"**/.vscode/*.json": "jsonc"
},
"C_Cpp.clang_format_path": "/usr/bin/clang-format-13"
}
}
}
}

View File

@@ -11,6 +11,7 @@ on:
- ".github/workflows/**"
- "requirements*.txt"
- "platformio.ini"
- "script/platformio_install_deps.py"
pull_request:
paths:
@@ -18,6 +19,7 @@ on:
- ".github/workflows/**"
- "requirements*.txt"
- "platformio.ini"
- "script/platformio_install_deps.py"
permissions:
contents: read

View File

@@ -23,6 +23,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 5
matrix:
include:
- id: ci-custom

View File

@@ -117,7 +117,7 @@ jobs:
--suffix "${{ matrix.image.suffix }}"
- name: Build and push
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
file: ./docker/Dockerfile

View File

@@ -0,0 +1,60 @@
---
name: Synchronise Device Classes from Home Assistant
on:
workflow_dispatch:
schedule:
- cron: '45 6 * * *'
permissions:
contents: write
pull-requests: write
jobs:
sync:
name: Sync Device Classes
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout Home Assistant
uses: actions/checkout@v3
with:
repository: home-assistant/core
path: lib/home-assistant
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Install Home Assistant
run: |
python -m pip install --upgrade pip
pip install -e lib/home-assistant
- name: Sync
run: |
python ./script/sync-device_class.py
- name: Get PR template
id: pr-template-body
run: |
body=$(cat .github/PULL_REQUEST_TEMPLATE.md)
delimiter="$(openssl rand -hex 8)"
echo "body<<$delimiter" >> $GITHUB_OUTPUT
echo "$body" >> $GITHUB_OUTPUT
echo "$delimiter" >> $GITHUB_OUTPUT
- name: Commit changes
uses: peter-evans/create-pull-request@v5
with:
commit-message: "Synchronise Device Classes from Home Assistant"
committer: esphomebot <esphome@nabucasa.com>
author: esphomebot <esphome@nabucasa.com>
branch: sync/device-classes/
branch-suffix: timestamp
delete-branch: true
title: "Synchronise Device Classes from Home Assistant"
body: ${{ steps.pr-template-body.outputs.body }}

View File

@@ -2,8 +2,8 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/ambv/black
rev: 23.1.0
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
args:
@@ -27,7 +27,7 @@ repos:
- --branch=release
- --branch=beta
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
rev: v3.3.2
hooks:
- id: pyupgrade
args: [--py39-plus]

15
.vscode/tasks.json vendored
View File

@@ -2,15 +2,24 @@
"version": "2.0.0",
"tasks": [
{
"label": "run",
"label": "Run Dashboard",
"type": "shell",
"command": "python3 -m esphome dashboard config/",
"command": "${command:python.interpreterPath}",
"args": [
"-m",
"esphome",
"dashboard",
"config/"
],
"problemMatcher": []
},
{
"label": "clang-tidy",
"type": "shell",
"command": "./script/clang-tidy",
"command": "${command:python.interpreterPath}",
"args": [
"./script/clang-tidy"
],
"problemMatcher": [
{
"owner": "clang-tidy",

View File

@@ -21,6 +21,7 @@ esphome/components/airthings_wave_mini/* @ncareau
esphome/components/airthings_wave_plus/* @jeromelaban
esphome/components/am43/* @buxtronix
esphome/components/am43/cover/* @buxtronix
esphome/components/am43/sensor/* @buxtronix
esphome/components/analog_threshold/* @ianchi
esphome/components/animation/* @syndlex
esphome/components/anova/* @buxtronix
@@ -83,6 +84,7 @@ esphome/components/esp32_ble_server/* @jesserockz
esphome/components/esp32_camera_web_server/* @ayufan
esphome/components/esp32_can/* @Sympatron
esphome/components/esp32_improv/* @jesserockz
esphome/components/esp32_rmt_led_strip/* @jesserockz
esphome/components/esp8266/* @esphome/core
esphome/components/ethernet_info/* @gtjadsonsantos
esphome/components/exposure_notifications/* @OttoWinter
@@ -94,6 +96,7 @@ esphome/components/feedback/* @ianchi
esphome/components/fingerprint_grow/* @OnFreund @loongyh
esphome/components/fs3000/* @kahrendt
esphome/components/globals/* @esphome/core
esphome/components/gp8403/* @jesserockz
esphome/components/gpio/* @esphome/core
esphome/components/gps/* @coogle
esphome/components/graph/* @synco
@@ -106,11 +109,16 @@ esphome/components/heatpumpir/* @rob-deutsch
esphome/components/hitachi_ac424/* @sourabhjaiswal
esphome/components/homeassistant/* @OttoWinter
esphome/components/honeywellabp/* @RubyBailey
esphome/components/host/* @esphome/core
esphome/components/hrxl_maxsonar_wr/* @netmikey
esphome/components/hte501/* @Stock-M
esphome/components/hydreon_rgxx/* @functionpointer
esphome/components/hyt271/* @Philippe12
esphome/components/i2c/* @esphome/core
esphome/components/i2s_audio/* @jesserockz
esphome/components/i2s_audio/media_player/* @jesserockz
esphome/components/i2s_audio/microphone/* @jesserockz
esphome/components/i2s_audio/speaker/* @jesserockz
esphome/components/ili9xxx/* @nielsnl68
esphome/components/improv_base/* @esphome/core
esphome/components/improv_serial/* @esphome/core
@@ -136,6 +144,7 @@ esphome/components/ltr390/* @sjtrny
esphome/components/matrix_keypad/* @ssieb
esphome/components/max31865/* @DAVe3283
esphome/components/max44009/* @berfenger
esphome/components/max6956/* @looping40
esphome/components/max7219digit/* @rspaargaren
esphome/components/max9611/* @mckaymatthew
esphome/components/mcp23008/* @jesserockz
@@ -154,11 +163,14 @@ esphome/components/mcp9808/* @k7hpn
esphome/components/md5/* @esphome/core
esphome/components/mdns/* @esphome/core
esphome/components/media_player/* @jesserockz
esphome/components/microphone/* @jesserockz
esphome/components/mics_4514/* @jesserockz
esphome/components/midea/* @dudanov
esphome/components/midea_ir/* @dudanov
esphome/components/mitsubishi/* @RubyBailey
esphome/components/mlx90393/* @functionpointer
esphome/components/mlx90614/* @jesserockz
esphome/components/mmc5603/* @benhoff
esphome/components/modbus_controller/* @martgras
esphome/components/modbus_controller/binary_sensor/* @martgras
esphome/components/modbus_controller/number/* @martgras
@@ -182,6 +194,7 @@ esphome/components/nfc/* @jesserockz
esphome/components/number/* @esphome/core
esphome/components/ota/* @esphome/core
esphome/components/output/* @esphome/core
esphome/components/pca6416a/* @Mat931
esphome/components/pca9554/* @hwstar
esphome/components/pcf85063/* @brogon
esphome/components/pid/* @OttoWinter
@@ -228,7 +241,7 @@ esphome/components/shutdown/* @esphome/core @jsuanet
esphome/components/sigma_delta_output/* @Cat-Ion
esphome/components/sim800l/* @glmnet
esphome/components/sm10bit_base/* @Cossid
esphome/components/sm2135/* @BoukeHaarsma23
esphome/components/sm2135/* @BoukeHaarsma23 @dd32 @matika77
esphome/components/sm2235/* @Cossid
esphome/components/sm2335/* @Cossid
esphome/components/sml/* @alengwenus
@@ -236,6 +249,7 @@ esphome/components/smt100/* @piechade
esphome/components/sn74hc165/* @jesserockz
esphome/components/socket/* @esphome/core
esphome/components/sonoff_d1/* @anatoly-savchenkov
esphome/components/speaker/* @jesserockz
esphome/components/spi/* @esphome/core
esphome/components/sprinkler/* @kbx81
esphome/components/sps30/* @martgras
@@ -286,6 +300,7 @@ esphome/components/ufire_ise/* @pvizeli
esphome/components/ultrasonic/* @OttoWinter
esphome/components/vbus/* @ssieb
esphome/components/version/* @esphome/core
esphome/components/voice_assistant/* @jesserockz
esphome/components/wake_on_lan/* @willwill2will54
esphome/components/web_server_base/* @OttoWinter
esphome/components/whirlpool/* @glmnet

View File

@@ -24,8 +24,9 @@ RUN \
python3-setuptools=52.0.0-4 \
python3-pil=8.1.2+dfsg-0.3+deb11u1 \
python3-cryptography=3.3.2-1 \
python3-venv=3.9.2-3 \
iputils-ping=3:20210202-1 \
git=1:2.30.2-1 \
git=1:2.30.2-1+deb11u2 \
curl=7.74.0-1.3+deb11u7 \
openssh-client=1:8.4p1-5+deb11u1 \
&& rm -rf \
@@ -59,10 +60,10 @@ RUN \
# First install requirements to leverage caching when requirements don't change
COPY requirements.txt requirements_optional.txt docker/platformio_install_deps.py platformio.ini /
COPY requirements.txt requirements_optional.txt script/platformio_install_deps.py platformio.ini /
RUN \
pip3 install --no-cache-dir -r /requirements.txt -r /requirements_optional.txt \
&& /platformio_install_deps.py /platformio.ini
&& /platformio_install_deps.py /platformio.ini --libraries
# ======================= docker-type image =======================

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env python3
# This script is used in the docker containers to preinstall
# all platformio libraries in the global storage
import configparser
import subprocess
import sys
config = configparser.ConfigParser(inline_comment_prefixes=(';', ))
config.read(sys.argv[1])
libs = []
# Extract from every lib_deps key in all sections
for section in config.sections():
conf = config[section]
if "lib_deps" not in conf:
continue
for lib_dep in conf["lib_deps"].splitlines():
if not lib_dep:
# Empty line or comment
continue
if lib_dep.startswith("${"):
# Extending from another section
continue
if "@" not in lib_dep:
# No version pinned, this is an internal lib
continue
libs.append(lib_dep)
subprocess.check_call(['platformio', 'lib', '-g', 'install', *libs])

View File

@@ -152,6 +152,8 @@ def run_miniterm(config, port):
_LOGGER.error("Could not connect to serial port %s", port)
return 1
return 0
def wrap_to_code(name, comp):
coro = coroutine(comp.to_code)
@@ -930,6 +932,8 @@ def run_esphome(argv):
_LOGGER.error(e, exc_info=args.verbose)
return 1
_LOGGER.info("ESPHome %s", const.__version__)
for conf_path in args.configuration:
if any(os.path.basename(conf_path) == x for x in SECRETS_FILES):
_LOGGER.warning("Skipping secrets file %s", conf_path)

View File

@@ -1 +1,118 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import CONF_INPUT
from esphome.core import CORE
from esphome.components.esp32 import get_esp32_variant
from esphome.components.esp32.const import (
VARIANT_ESP32,
VARIANT_ESP32C3,
VARIANT_ESP32H2,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
)
CODEOWNERS = ["@esphome/core"]
ATTENUATION_MODES = {
"0db": cg.global_ns.ADC_ATTEN_DB_0,
"2.5db": cg.global_ns.ADC_ATTEN_DB_2_5,
"6db": cg.global_ns.ADC_ATTEN_DB_6,
"11db": cg.global_ns.ADC_ATTEN_DB_11,
"auto": "auto",
}
adc1_channel_t = cg.global_ns.enum("adc1_channel_t")
# From https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/adc_common.h
# pin to adc1 channel mapping
ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
VARIANT_ESP32: {
36: adc1_channel_t.ADC1_CHANNEL_0,
37: adc1_channel_t.ADC1_CHANNEL_1,
38: adc1_channel_t.ADC1_CHANNEL_2,
39: adc1_channel_t.ADC1_CHANNEL_3,
32: adc1_channel_t.ADC1_CHANNEL_4,
33: adc1_channel_t.ADC1_CHANNEL_5,
34: adc1_channel_t.ADC1_CHANNEL_6,
35: adc1_channel_t.ADC1_CHANNEL_7,
},
VARIANT_ESP32S2: {
1: adc1_channel_t.ADC1_CHANNEL_0,
2: adc1_channel_t.ADC1_CHANNEL_1,
3: adc1_channel_t.ADC1_CHANNEL_2,
4: adc1_channel_t.ADC1_CHANNEL_3,
5: adc1_channel_t.ADC1_CHANNEL_4,
6: adc1_channel_t.ADC1_CHANNEL_5,
7: adc1_channel_t.ADC1_CHANNEL_6,
8: adc1_channel_t.ADC1_CHANNEL_7,
9: adc1_channel_t.ADC1_CHANNEL_8,
10: adc1_channel_t.ADC1_CHANNEL_9,
},
VARIANT_ESP32S3: {
1: adc1_channel_t.ADC1_CHANNEL_0,
2: adc1_channel_t.ADC1_CHANNEL_1,
3: adc1_channel_t.ADC1_CHANNEL_2,
4: adc1_channel_t.ADC1_CHANNEL_3,
5: adc1_channel_t.ADC1_CHANNEL_4,
6: adc1_channel_t.ADC1_CHANNEL_5,
7: adc1_channel_t.ADC1_CHANNEL_6,
8: adc1_channel_t.ADC1_CHANNEL_7,
9: adc1_channel_t.ADC1_CHANNEL_8,
10: adc1_channel_t.ADC1_CHANNEL_9,
},
VARIANT_ESP32C3: {
0: adc1_channel_t.ADC1_CHANNEL_0,
1: adc1_channel_t.ADC1_CHANNEL_1,
2: adc1_channel_t.ADC1_CHANNEL_2,
3: adc1_channel_t.ADC1_CHANNEL_3,
4: adc1_channel_t.ADC1_CHANNEL_4,
},
VARIANT_ESP32H2: {
0: adc1_channel_t.ADC1_CHANNEL_0,
1: adc1_channel_t.ADC1_CHANNEL_1,
2: adc1_channel_t.ADC1_CHANNEL_2,
3: adc1_channel_t.ADC1_CHANNEL_3,
4: adc1_channel_t.ADC1_CHANNEL_4,
},
}
def validate_adc_pin(value):
if str(value).upper() == "VCC":
return cv.only_on_esp8266("VCC")
if str(value).upper() == "TEMPERATURE":
return cv.only_on_rp2040("TEMPERATURE")
if CORE.is_esp32:
value = pins.internal_gpio_input_pin_number(value)
variant = get_esp32_variant()
if variant not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL:
raise cv.Invalid(f"This ESP32 variant ({variant}) is not supported")
if value not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL[variant]:
raise cv.Invalid(f"{variant} doesn't support ADC on this pin")
return pins.internal_gpio_input_pin_schema(value)
if CORE.is_esp8266:
from esphome.components.esp8266.gpio import CONF_ANALOG
value = pins.internal_gpio_pin_number({CONF_ANALOG: True, CONF_INPUT: True})(
value
)
if value != 17: # A0
raise cv.Invalid("ESP8266: Only pin A0 (GPIO17) supports ADC.")
return pins.gpio_pin_schema(
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
)(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

View File

@@ -1,133 +1,27 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import sensor, voltage_sampler
from esphome.components.esp32 import get_esp32_variant
from esphome.const import (
CONF_ATTENUATION,
CONF_RAW,
CONF_ID,
CONF_INPUT,
CONF_NUMBER,
CONF_PIN,
CONF_RAW,
DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT,
UNIT_VOLT,
)
from esphome.core import CORE
from esphome.components.esp32 import get_esp32_variant
from esphome.components.esp32.const import (
VARIANT_ESP32,
VARIANT_ESP32C3,
VARIANT_ESP32H2,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
from . import (
ATTENUATION_MODES,
ESP32_VARIANT_ADC1_PIN_TO_CHANNEL,
validate_adc_pin,
)
AUTO_LOAD = ["voltage_sampler"]
ATTENUATION_MODES = {
"0db": cg.global_ns.ADC_ATTEN_DB_0,
"2.5db": cg.global_ns.ADC_ATTEN_DB_2_5,
"6db": cg.global_ns.ADC_ATTEN_DB_6,
"11db": cg.global_ns.ADC_ATTEN_DB_11,
"auto": "auto",
}
adc1_channel_t = cg.global_ns.enum("adc1_channel_t")
# From https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/adc_common.h
# pin to adc1 channel mapping
ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
VARIANT_ESP32: {
36: adc1_channel_t.ADC1_CHANNEL_0,
37: adc1_channel_t.ADC1_CHANNEL_1,
38: adc1_channel_t.ADC1_CHANNEL_2,
39: adc1_channel_t.ADC1_CHANNEL_3,
32: adc1_channel_t.ADC1_CHANNEL_4,
33: adc1_channel_t.ADC1_CHANNEL_5,
34: adc1_channel_t.ADC1_CHANNEL_6,
35: adc1_channel_t.ADC1_CHANNEL_7,
},
VARIANT_ESP32S2: {
1: adc1_channel_t.ADC1_CHANNEL_0,
2: adc1_channel_t.ADC1_CHANNEL_1,
3: adc1_channel_t.ADC1_CHANNEL_2,
4: adc1_channel_t.ADC1_CHANNEL_3,
5: adc1_channel_t.ADC1_CHANNEL_4,
6: adc1_channel_t.ADC1_CHANNEL_5,
7: adc1_channel_t.ADC1_CHANNEL_6,
8: adc1_channel_t.ADC1_CHANNEL_7,
9: adc1_channel_t.ADC1_CHANNEL_8,
10: adc1_channel_t.ADC1_CHANNEL_9,
},
VARIANT_ESP32S3: {
1: adc1_channel_t.ADC1_CHANNEL_0,
2: adc1_channel_t.ADC1_CHANNEL_1,
3: adc1_channel_t.ADC1_CHANNEL_2,
4: adc1_channel_t.ADC1_CHANNEL_3,
5: adc1_channel_t.ADC1_CHANNEL_4,
6: adc1_channel_t.ADC1_CHANNEL_5,
7: adc1_channel_t.ADC1_CHANNEL_6,
8: adc1_channel_t.ADC1_CHANNEL_7,
9: adc1_channel_t.ADC1_CHANNEL_8,
10: adc1_channel_t.ADC1_CHANNEL_9,
},
VARIANT_ESP32C3: {
0: adc1_channel_t.ADC1_CHANNEL_0,
1: adc1_channel_t.ADC1_CHANNEL_1,
2: adc1_channel_t.ADC1_CHANNEL_2,
3: adc1_channel_t.ADC1_CHANNEL_3,
4: adc1_channel_t.ADC1_CHANNEL_4,
},
VARIANT_ESP32H2: {
0: adc1_channel_t.ADC1_CHANNEL_0,
1: adc1_channel_t.ADC1_CHANNEL_1,
2: adc1_channel_t.ADC1_CHANNEL_2,
3: adc1_channel_t.ADC1_CHANNEL_3,
4: adc1_channel_t.ADC1_CHANNEL_4,
},
}
def validate_adc_pin(value):
if str(value).upper() == "VCC":
return cv.only_on_esp8266("VCC")
if str(value).upper() == "TEMPERATURE":
return cv.only_on_rp2040("TEMPERATURE")
if CORE.is_esp32:
value = pins.internal_gpio_input_pin_number(value)
variant = get_esp32_variant()
if variant not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL:
raise cv.Invalid(f"This ESP32 variant ({variant}) is not supported")
if value not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL[variant]:
raise cv.Invalid(f"{variant} doesn't support ADC on this pin")
return pins.internal_gpio_input_pin_schema(value)
if CORE.is_esp8266:
from esphome.components.esp8266.gpio import CONF_ANALOG
value = pins.internal_gpio_pin_number({CONF_ANALOG: True, CONF_INPUT: True})(
value
)
if value != 17: # A0
raise cv.Invalid("ESP8266: Only pin A0 (GPIO17) supports ADC.")
return pins.gpio_pin_schema(
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
)(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
def validate_config(config):
if config[CONF_RAW] and config.get(CONF_ATTENUATION, None) == "auto":

View File

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

View File

@@ -5,7 +5,7 @@ from esphome.const import CONF_ID, CONF_PIN
CODEOWNERS = ["@buxtronix"]
DEPENDENCIES = ["ble_client"]
AUTO_LOAD = ["am43", "sensor"]
AUTO_LOAD = ["am43"]
CONF_INVERT_POSITION = "invert_position"
@@ -27,10 +27,10 @@ CONFIG_SCHEMA = (
)
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_pin(config[CONF_PIN]))
cg.add(var.set_invert_position(config[CONF_INVERT_POSITION]))
yield cg.register_component(var, config)
yield cover.register_cover(var, config)
yield ble_client.register_ble_node(var, config)
await cg.register_component(var, config)
await cover.register_cover(var, config)
await ble_client.register_ble_node(var, config)

View File

@@ -40,6 +40,7 @@ void Am43Component::loop() {
CoverTraits Am43Component::get_traits() {
auto traits = CoverTraits();
traits.set_supports_stop(true);
traits.set_supports_position(true);
traits.set_supports_tilt(false);
traits.set_is_assumed_state(false);

View File

@@ -11,6 +11,7 @@ from esphome.const import (
UNIT_PERCENT,
)
AUTO_LOAD = ["am43"]
CODEOWNERS = ["@buxtronix"]
am43_ns = cg.esphome_ns.namespace("am43")
@@ -38,15 +39,15 @@ CONFIG_SCHEMA = (
)
def to_code(config):
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield ble_client.register_ble_node(var, config)
await cg.register_component(var, config)
await ble_client.register_ble_node(var, config)
if CONF_BATTERY_LEVEL in config:
sens = yield sensor.new_sensor(config[CONF_BATTERY_LEVEL])
sens = await sensor.new_sensor(config[CONF_BATTERY_LEVEL])
cg.add(var.set_battery(sens))
if CONF_ILLUMINANCE in config:
sens = yield sensor.new_sensor(config[CONF_ILLUMINANCE])
sens = await sensor.new_sensor(config[CONF_ILLUMINANCE])
cg.add(var.set_illuminance(sens))

View File

@@ -1,6 +1,6 @@
#include "am43.h"
#include "esphome/core/log.h"
#include "am43_sensor.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
#ifdef USE_ESP32

View File

@@ -4,7 +4,6 @@ from esphome.components import i2c
from esphome.const import CONF_ID
DEPENDENCIES = ["i2c"]
AUTO_LOAD = ["sensor", "binary_sensor"]
MULTI_CONF = True
CONF_APDS9960_ID = "apds9960_id"

View File

@@ -116,8 +116,12 @@ void APDS9960::setup() {
APDS9960_WRITE_BYTE(0x80, val);
}
bool APDS9960::is_color_enabled_() const {
return this->red_channel_ != nullptr || this->green_channel_ != nullptr || this->blue_channel_ != nullptr ||
this->clear_channel_ != nullptr;
#ifdef USE_SENSOR
return this->red_sensor_ != nullptr || this->green_sensor_ != nullptr || this->blue_sensor_ != nullptr ||
this->clear_sensor_ != nullptr;
#else
return false;
#endif
}
void APDS9960::dump_config() {
@@ -125,6 +129,15 @@ void APDS9960::dump_config() {
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
#ifdef USE_SENSOR
LOG_SENSOR(" ", "Red channel", this->red_sensor_);
LOG_SENSOR(" ", "Green channel", this->green_sensor_);
LOG_SENSOR(" ", "Blue channel", this->blue_sensor_);
LOG_SENSOR(" ", "Clear channel", this->clear_sensor_);
LOG_SENSOR(" ", "Proximity", this->proximity_sensor_);
#endif
if (this->is_failed()) {
switch (this->error_code_) {
case COMMUNICATION_FAILED:
@@ -181,17 +194,22 @@ void APDS9960::read_color_data_(uint8_t status) {
float blue_perc = (uint_blue / float(UINT16_MAX)) * 100.0f;
ESP_LOGD(TAG, "Got clear=%.1f%% red=%.1f%% green=%.1f%% blue=%.1f%%", clear_perc, red_perc, green_perc, blue_perc);
if (this->clear_channel_ != nullptr)
this->clear_channel_->publish_state(clear_perc);
if (this->red_channel_ != nullptr)
this->red_channel_->publish_state(red_perc);
if (this->green_channel_ != nullptr)
this->green_channel_->publish_state(green_perc);
if (this->blue_channel_ != nullptr)
this->blue_channel_->publish_state(blue_perc);
#ifdef USE_SENSOR
if (this->clear_sensor_ != nullptr)
this->clear_sensor_->publish_state(clear_perc);
if (this->red_sensor_ != nullptr)
this->red_sensor_->publish_state(red_perc);
if (this->green_sensor_ != nullptr)
this->green_sensor_->publish_state(green_perc);
if (this->blue_sensor_ != nullptr)
this->blue_sensor_->publish_state(blue_perc);
#endif
}
void APDS9960::read_proximity_data_(uint8_t status) {
if (this->proximity_ == nullptr)
#ifndef USE_SENSOR
return;
#else
if (this->proximity_sensor_ == nullptr)
return;
if ((status & 0b10) == 0x00) {
@@ -204,7 +222,8 @@ void APDS9960::read_proximity_data_(uint8_t status) {
float prox_perc = (prox / float(UINT8_MAX)) * 100.0f;
ESP_LOGD(TAG, "Got proximity=%.1f%%", prox_perc);
this->proximity_->publish_state(prox_perc);
this->proximity_sensor_->publish_state(prox_perc);
#endif
}
void APDS9960::read_gesture_data_() {
if (!this->is_gesture_enabled_())
@@ -256,28 +275,29 @@ void APDS9960::read_gesture_data_() {
}
}
void APDS9960::report_gesture_(int gesture) {
#ifdef USE_BINARY_SENSOR
binary_sensor::BinarySensor *bin;
switch (gesture) {
case 1:
bin = this->up_direction_;
bin = this->up_direction_binary_sensor_;
this->gesture_up_started_ = false;
this->gesture_down_started_ = false;
ESP_LOGD(TAG, "Got gesture UP");
break;
case 2:
bin = this->down_direction_;
bin = this->down_direction_binary_sensor_;
this->gesture_up_started_ = false;
this->gesture_down_started_ = false;
ESP_LOGD(TAG, "Got gesture DOWN");
break;
case 3:
bin = this->left_direction_;
bin = this->left_direction_binary_sensor_;
this->gesture_left_started_ = false;
this->gesture_right_started_ = false;
ESP_LOGD(TAG, "Got gesture LEFT");
break;
case 4:
bin = this->right_direction_;
bin = this->right_direction_binary_sensor_;
this->gesture_left_started_ = false;
this->gesture_right_started_ = false;
ESP_LOGD(TAG, "Got gesture RIGHT");
@@ -290,6 +310,7 @@ void APDS9960::report_gesture_(int gesture) {
bin->publish_state(true);
bin->publish_state(false);
}
#endif
}
void APDS9960::process_dataset_(int up, int down, int left, int right) {
/* Algorithm: (see Figure 11 in datasheet)
@@ -365,10 +386,22 @@ void APDS9960::process_dataset_(int up, int down, int left, int right) {
}
}
float APDS9960::get_setup_priority() const { return setup_priority::DATA; }
bool APDS9960::is_proximity_enabled_() const { return this->proximity_ != nullptr || this->is_gesture_enabled_(); }
bool APDS9960::is_proximity_enabled_() const {
return
#ifdef USE_SENSOR
this->proximity_sensor_ != nullptr
#else
false
#endif
|| this->is_gesture_enabled_();
}
bool APDS9960::is_gesture_enabled_() const {
return this->up_direction_ != nullptr || this->left_direction_ != nullptr || this->down_direction_ != nullptr ||
this->right_direction_ != nullptr;
#ifdef USE_BINARY_SENSOR
return this->up_direction_binary_sensor_ != nullptr || this->left_direction_binary_sensor_ != nullptr ||
this->down_direction_binary_sensor_ != nullptr || this->right_direction_binary_sensor_ != nullptr;
#else
return false;
#endif
}
} // namespace apds9960

View File

@@ -1,14 +1,34 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
namespace esphome {
namespace apds9960 {
class APDS9960 : public PollingComponent, public i2c::I2CDevice {
#ifdef USE_SENSOR
SUB_SENSOR(red)
SUB_SENSOR(green)
SUB_SENSOR(blue)
SUB_SENSOR(clear)
SUB_SENSOR(proximity)
#endif
#ifdef USE_BINARY_SENSOR
SUB_BINARY_SENSOR(up_direction)
SUB_BINARY_SENSOR(right_direction)
SUB_BINARY_SENSOR(down_direction)
SUB_BINARY_SENSOR(left_direction)
#endif
public:
void setup() override;
void dump_config() override;
@@ -23,16 +43,6 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice {
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_green_channel(sensor::Sensor *green_channel) { green_channel_ = green_channel; }
void set_blue_channel(sensor::Sensor *blue_channel) { blue_channel_ = blue_channel; }
void set_clear_channel(sensor::Sensor *clear_channel) { clear_channel_ = clear_channel; }
void set_up_direction(binary_sensor::BinarySensor *up_direction) { up_direction_ = up_direction; }
void set_right_direction(binary_sensor::BinarySensor *right_direction) { right_direction_ = right_direction; }
void set_down_direction(binary_sensor::BinarySensor *down_direction) { down_direction_ = down_direction; }
void set_left_direction(binary_sensor::BinarySensor *left_direction) { left_direction_ = left_direction; }
void set_proximity(sensor::Sensor *proximity) { proximity_ = proximity; }
protected:
bool is_color_enabled_() const;
bool is_proximity_enabled_() const;
@@ -50,15 +60,6 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice {
uint8_t gesture_gain_;
uint8_t gesture_wait_time_;
sensor::Sensor *red_channel_{nullptr};
sensor::Sensor *green_channel_{nullptr};
sensor::Sensor *blue_channel_{nullptr};
sensor::Sensor *clear_channel_{nullptr};
binary_sensor::BinarySensor *up_direction_{nullptr};
binary_sensor::BinarySensor *right_direction_{nullptr};
binary_sensor::BinarySensor *down_direction_{nullptr};
binary_sensor::BinarySensor *left_direction_{nullptr};
sensor::Sensor *proximity_{nullptr};
enum ErrorCode {
NONE = 0,
COMMUNICATION_FAILED,

View File

@@ -6,19 +6,14 @@ from . import APDS9960, CONF_APDS9960_ID
DEPENDENCIES = ["apds9960"]
DIRECTIONS = {
"UP": "set_up_direction",
"DOWN": "set_down_direction",
"LEFT": "set_left_direction",
"RIGHT": "set_right_direction",
}
DIRECTIONS = ["up", "down", "left", "right"]
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_MOVING
).extend(
{
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, upper=True),
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, lower=True),
}
)
@@ -26,5 +21,5 @@ CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(
async def to_code(config):
hub = await cg.get_variable(config[CONF_APDS9960_ID])
var = await binary_sensor.new_binary_sensor(config)
func = getattr(hub, DIRECTIONS[config[CONF_DIRECTION]])
func = getattr(hub, f"set_{config[CONF_DIRECTION]}_direction_binary_sensor")
cg.add(func(var))

View File

@@ -11,13 +11,7 @@ from . import APDS9960, CONF_APDS9960_ID
DEPENDENCIES = ["apds9960"]
TYPES = {
"CLEAR": "set_clear_channel",
"RED": "set_red_channel",
"GREEN": "set_green_channel",
"BLUE": "set_blue_channel",
"PROXIMITY": "set_proximity",
}
TYPES = ["clear", "red", "green", "blue", "proximity"]
CONFIG_SCHEMA = sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
@@ -26,7 +20,7 @@ CONFIG_SCHEMA = sensor.sensor_schema(
state_class=STATE_CLASS_MEASUREMENT,
).extend(
{
cv.Required(CONF_TYPE): cv.one_of(*TYPES, upper=True),
cv.Required(CONF_TYPE): cv.one_of(*TYPES, lower=True),
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
}
)
@@ -35,5 +29,5 @@ CONFIG_SCHEMA = sensor.sensor_schema(
async def to_code(config):
hub = await cg.get_variable(config[CONF_APDS9960_ID])
var = await sensor.new_sensor(config)
func = getattr(hub, TYPES[config[CONF_TYPE]])
func = getattr(hub, f"set_{config[CONF_TYPE]}_sensor")
cg.add(func(var))

View File

@@ -53,6 +53,9 @@ service APIConnection {
rpc bluetooth_gatt_write_descriptor(BluetoothGATTWriteDescriptorRequest) returns (void) {}
rpc bluetooth_gatt_notify(BluetoothGATTNotifyRequest) returns (void) {}
rpc subscribe_bluetooth_connections_free(SubscribeBluetoothConnectionsFreeRequest) returns (BluetoothConnectionsFreeResponse) {}
rpc unsubscribe_bluetooth_le_advertisements(UnsubscribeBluetoothLEAdvertisementsRequest) returns (void) {}
rpc subscribe_voice_assistant(SubscribeVoiceAssistantRequest) returns (void) {}
}
@@ -208,6 +211,8 @@ message DeviceInfoResponse {
string manufacturer = 12;
string friendly_name = 13;
uint32 voice_assistant_version = 14;
}
message ListEntitiesRequest {
@@ -283,6 +288,7 @@ message ListEntitiesCoverResponse {
bool disabled_by_default = 9;
string icon = 10;
EntityCategory entity_category = 11;
bool supports_stop = 12;
}
enum LegacyCoverState {
@@ -856,8 +862,7 @@ message ClimateStateResponse {
float target_temperature = 4;
float target_temperature_low = 5;
float target_temperature_high = 6;
// For older peers, equal to preset == CLIMATE_PRESET_AWAY
bool legacy_away = 7;
bool unused_legacy_away = 7;
ClimateAction action = 8;
ClimateFanMode fan_mode = 9;
ClimateSwingMode swing_mode = 10;
@@ -880,9 +885,8 @@ message ClimateCommandRequest {
float target_temperature_low = 7;
bool has_target_temperature_high = 8;
float target_temperature_high = 9;
// legacy, for older peers, newer ones should use CLIMATE_PRESET_AWAY in preset
bool has_legacy_away = 10;
bool legacy_away = 11;
bool unused_has_legacy_away = 10;
bool unused_legacy_away = 11;
bool has_fan_mode = 12;
ClimateFanMode fan_mode = 13;
bool has_swing_mode = 14;
@@ -1125,6 +1129,7 @@ message MediaPlayerCommandRequest {
message SubscribeBluetoothLEAdvertisementsRequest {
option (id) = 66;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
}
message BluetoothServiceData {
@@ -1361,6 +1366,12 @@ message BluetoothDeviceUnpairingResponse {
int32 error = 3;
}
message UnsubscribeBluetoothLEAdvertisementsRequest {
option (id) = 87;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_BLUETOOTH_PROXY";
}
message BluetoothDeviceClearCacheResponse {
option (id) = 88;
option (source) = SOURCE_SERVER;
@@ -1370,3 +1381,55 @@ message BluetoothDeviceClearCacheResponse {
bool success = 2;
int32 error = 3;
}
// ==================== PUSH TO TALK ====================
message SubscribeVoiceAssistantRequest {
option (id) = 89;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_VOICE_ASSISTANT";
bool subscribe = 1;
}
message VoiceAssistantRequest {
option (id) = 90;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_VOICE_ASSISTANT";
bool start = 1;
}
message VoiceAssistantResponse {
option (id) = 91;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_VOICE_ASSISTANT";
uint32 port = 1;
bool error = 2;
}
enum VoiceAssistantEvent {
VOICE_ASSISTANT_ERROR = 0;
VOICE_ASSISTANT_RUN_START = 1;
VOICE_ASSISTANT_RUN_END = 2;
VOICE_ASSISTANT_STT_START = 3;
VOICE_ASSISTANT_STT_END = 4;
VOICE_ASSISTANT_INTENT_START = 5;
VOICE_ASSISTANT_INTENT_END = 6;
VOICE_ASSISTANT_TTS_START = 7;
VOICE_ASSISTANT_TTS_END = 8;
}
message VoiceAssistantEventData {
string name = 1;
string value = 2;
}
message VoiceAssistantEventResponse {
option (id) = 92;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_VOICE_ASSISTANT";
VoiceAssistantEvent event_type = 1;
repeated VoiceAssistantEventData data = 2;
}

View File

@@ -1,5 +1,6 @@
#include "api_connection.h"
#include <cerrno>
#include <cinttypes>
#include "esphome/components/network/util.h"
#include "esphome/core/entity_base.h"
#include "esphome/core/hal.h"
@@ -15,6 +16,9 @@
#ifdef USE_BLUETOOTH_PROXY
#include "esphome/components/bluetooth_proxy/bluetooth_proxy.h"
#endif
#ifdef USE_VOICE_ASSISTANT
#include "esphome/components/voice_assistant/voice_assistant.h"
#endif
namespace esphome {
namespace api {
@@ -219,6 +223,7 @@ bool APIConnection::send_cover_info(cover::Cover *cover) {
msg.assumed_state = traits.get_is_assumed_state();
msg.supports_position = traits.get_supports_position();
msg.supports_tilt = traits.get_supports_tilt();
msg.supports_stop = traits.get_supports_stop();
msg.device_class = cover->get_device_class();
msg.disabled_by_default = cover->is_disabled_by_default();
msg.icon = cover->get_icon();
@@ -526,7 +531,6 @@ bool APIConnection::send_climate_state(climate::Climate *climate) {
resp.custom_fan_mode = climate->custom_fan_mode.value();
if (traits.get_supports_presets() && climate->preset.has_value()) {
resp.preset = static_cast<enums::ClimatePreset>(climate->preset.value());
resp.legacy_away = resp.preset == enums::CLIMATE_PRESET_AWAY;
}
if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value())
resp.custom_preset = climate->custom_preset.value();
@@ -587,8 +591,6 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
call.set_target_temperature_low(msg.target_temperature_low);
if (msg.has_target_temperature_high)
call.set_target_temperature_high(msg.target_temperature_high);
if (msg.has_legacy_away)
call.set_preset(msg.legacy_away ? climate::CLIMATE_PRESET_AWAY : climate::CLIMATE_PRESET_HOME);
if (msg.has_fan_mode)
call.set_fan_mode(static_cast<climate::ClimateFanMode>(msg.fan_mode));
if (msg.has_custom_fan_mode)
@@ -892,6 +894,30 @@ BluetoothConnectionsFreeResponse APIConnection::subscribe_bluetooth_connections_
}
#endif
#ifdef USE_VOICE_ASSISTANT
bool APIConnection::request_voice_assistant(bool start) {
if (!this->voice_assistant_subscription_)
return false;
VoiceAssistantRequest msg;
msg.start = start;
return this->send_voice_assistant_request(msg);
}
void APIConnection::on_voice_assistant_response(const VoiceAssistantResponse &msg) {
if (voice_assistant::global_voice_assistant != nullptr) {
struct sockaddr_storage storage;
socklen_t len = sizeof(storage);
this->helper_->getpeername((struct sockaddr *) &storage, &len);
voice_assistant::global_voice_assistant->start(&storage, msg.port);
}
};
void APIConnection::on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) {
if (voice_assistant::global_voice_assistant != nullptr) {
voice_assistant::global_voice_assistant->on_event(msg);
}
}
#endif
bool APIConnection::send_log_message(int level, const char *tag, const char *line) {
if (this->log_subscription_ < level)
return false;
@@ -911,12 +937,12 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) {
this->helper_->set_log_info(client_info_);
this->client_api_version_major_ = msg.api_version_major;
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(),
ESP_LOGV(TAG, "Hello from client: '%s' | API Version %" PRIu32 ".%" PRIu32, this->client_info_.c_str(),
this->client_api_version_major_, this->client_api_version_minor_);
HelloResponse resp;
resp.api_version_major = 1;
resp.api_version_minor = 7;
resp.api_version_minor = 8;
resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
resp.name = App.get_name();
@@ -953,6 +979,8 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
resp.manufacturer = "Espressif";
#elif defined(USE_RP2040)
resp.manufacturer = "Raspberry Pi";
#elif defined(USE_HOST)
resp.manufacturer = "Host";
#endif
resp.model = ESPHOME_BOARD;
#ifdef USE_DEEP_SLEEP
@@ -969,6 +997,9 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
resp.bluetooth_proxy_version = bluetooth_proxy::global_bluetooth_proxy->has_active()
? bluetooth_proxy::ACTIVE_CONNECTIONS_VERSION
: bluetooth_proxy::PASSIVE_ONLY_VERSION;
#endif
#ifdef USE_VOICE_ASSISTANT
resp.voice_assistant_version = voice_assistant::global_voice_assistant->get_version();
#endif
return resp;
}

View File

@@ -6,6 +6,7 @@
#include "api_server.h"
#include "esphome/core/application.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include <vector>
@@ -97,6 +98,12 @@ class APIConnection : public APIServerConnection {
this->send_homeassistant_service_response(call);
}
#ifdef USE_BLUETOOTH_PROXY
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override {
this->bluetooth_le_advertisement_subscription_ = true;
}
void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override {
this->bluetooth_le_advertisement_subscription_ = false;
}
bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg);
void bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
@@ -117,6 +124,15 @@ class APIConnection : public APIServerConnection {
}
#endif
#ifdef USE_VOICE_ASSISTANT
void subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) override {
this->voice_assistant_subscription_ = msg.subscribe;
}
bool request_voice_assistant(bool start);
void on_voice_assistant_response(const VoiceAssistantResponse &msg) override;
void on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) override;
#endif
void on_disconnect_response(const DisconnectResponse &value) override;
void on_ping_response(const PingResponse &value) override {
// we initiated ping
@@ -150,9 +166,7 @@ class APIConnection : public APIServerConnection {
return {};
}
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_connection_setup() override {
return this->connection_state_ == ConnectionState ::CONNECTED || this->is_authenticated();
@@ -197,7 +211,12 @@ class APIConnection : public APIServerConnection {
uint32_t last_traffic_;
bool sent_ping_{false};
bool service_call_subscription_{false};
#ifdef USE_BLUETOOTH_PROXY
bool bluetooth_le_advertisement_subscription_{false};
#endif
#ifdef USE_VOICE_ASSISTANT
bool voice_assistant_subscription_{false};
#endif
bool next_close_ = false;
APIServer *parent_;
InitialStateIterator initial_state_iterator_;

View File

@@ -10,8 +10,8 @@
#include "noise/protocol.h"
#endif
#include "esphome/components/socket/socket.h"
#include "api_noise_context.h"
#include "esphome/components/socket/socket.h"
namespace esphome {
namespace api {
@@ -67,6 +67,7 @@ class APIFrameHelper {
virtual bool can_write_without_blocking() = 0;
virtual APIError write_packet(uint16_t type, const uint8_t *data, size_t len) = 0;
virtual std::string getpeername() = 0;
virtual int getpeername(struct sockaddr *addr, socklen_t *addrlen) = 0;
virtual APIError close() = 0;
virtual APIError shutdown(int how) = 0;
// Give this helper a name for logging
@@ -84,7 +85,10 @@ class APINoiseFrameHelper : public APIFrameHelper {
APIError read_packet(ReadPacketBuffer *buffer) override;
bool can_write_without_blocking() override;
APIError write_packet(uint16_t type, const uint8_t *payload, size_t len) override;
std::string getpeername() override { return socket_->getpeername(); }
std::string getpeername() override { return this->socket_->getpeername(); }
int getpeername(struct sockaddr *addr, socklen_t *addrlen) override {
return this->socket_->getpeername(addr, addrlen);
}
APIError close() override;
APIError shutdown(int how) override;
// Give this helper a name for logging
@@ -144,7 +148,10 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
APIError read_packet(ReadPacketBuffer *buffer) override;
bool can_write_without_blocking() override;
APIError write_packet(uint16_t type, const uint8_t *payload, size_t len) override;
std::string getpeername() override { return socket_->getpeername(); }
std::string getpeername() override { return this->socket_->getpeername(); }
int getpeername(struct sockaddr *addr, socklen_t *addrlen) override {
return this->socket_->getpeername(addr, addrlen);
}
APIError close() override;
APIError shutdown(int how) override;
// Give this helper a name for logging

View File

@@ -407,6 +407,32 @@ const char *proto_enum_to_string<enums::BluetoothDeviceRequestType>(enums::Bluet
}
}
#endif
#ifdef HAS_PROTO_MESSAGE_DUMP
template<> const char *proto_enum_to_string<enums::VoiceAssistantEvent>(enums::VoiceAssistantEvent value) {
switch (value) {
case enums::VOICE_ASSISTANT_ERROR:
return "VOICE_ASSISTANT_ERROR";
case enums::VOICE_ASSISTANT_RUN_START:
return "VOICE_ASSISTANT_RUN_START";
case enums::VOICE_ASSISTANT_RUN_END:
return "VOICE_ASSISTANT_RUN_END";
case enums::VOICE_ASSISTANT_STT_START:
return "VOICE_ASSISTANT_STT_START";
case enums::VOICE_ASSISTANT_STT_END:
return "VOICE_ASSISTANT_STT_END";
case enums::VOICE_ASSISTANT_INTENT_START:
return "VOICE_ASSISTANT_INTENT_START";
case enums::VOICE_ASSISTANT_INTENT_END:
return "VOICE_ASSISTANT_INTENT_END";
case enums::VOICE_ASSISTANT_TTS_START:
return "VOICE_ASSISTANT_TTS_START";
case enums::VOICE_ASSISTANT_TTS_END:
return "VOICE_ASSISTANT_TTS_END";
default:
return "UNKNOWN";
}
}
#endif
bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 2: {
@@ -594,6 +620,10 @@ bool DeviceInfoResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
this->bluetooth_proxy_version = value.as_uint32();
return true;
}
case 14: {
this->voice_assistant_version = value.as_uint32();
return true;
}
default:
return false;
}
@@ -654,6 +684,7 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(11, this->bluetooth_proxy_version);
buffer.encode_string(12, this->manufacturer);
buffer.encode_string(13, this->friendly_name);
buffer.encode_uint32(14, this->voice_assistant_version);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void DeviceInfoResponse::dump_to(std::string &out) const {
@@ -712,6 +743,11 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
out.append(" friendly_name: ");
out.append("'").append(this->friendly_name).append("'");
out.append("\n");
out.append(" voice_assistant_version: ");
sprintf(buffer, "%u", this->voice_assistant_version);
out.append(buffer);
out.append("\n");
out.append("}");
}
#endif
@@ -905,6 +941,10 @@ bool ListEntitiesCoverResponse::decode_varint(uint32_t field_id, ProtoVarInt val
this->entity_category = value.as_enum<enums::EntityCategory>();
return true;
}
case 12: {
this->supports_stop = value.as_bool();
return true;
}
default:
return false;
}
@@ -957,6 +997,7 @@ void ListEntitiesCoverResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_bool(9, this->disabled_by_default);
buffer.encode_string(10, this->icon);
buffer.encode_enum<enums::EntityCategory>(11, this->entity_category);
buffer.encode_bool(12, this->supports_stop);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void ListEntitiesCoverResponse::dump_to(std::string &out) const {
@@ -1006,6 +1047,10 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const {
out.append(" entity_category: ");
out.append(proto_enum_to_string<enums::EntityCategory>(this->entity_category));
out.append("\n");
out.append(" supports_stop: ");
out.append(YESNO(this->supports_stop));
out.append("\n");
out.append("}");
}
#endif
@@ -3613,7 +3658,7 @@ bool ClimateStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
return true;
}
case 7: {
this->legacy_away = value.as_bool();
this->unused_legacy_away = value.as_bool();
return true;
}
case 8: {
@@ -3683,7 +3728,7 @@ void ClimateStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_float(4, this->target_temperature);
buffer.encode_float(5, this->target_temperature_low);
buffer.encode_float(6, this->target_temperature_high);
buffer.encode_bool(7, this->legacy_away);
buffer.encode_bool(7, this->unused_legacy_away);
buffer.encode_enum<enums::ClimateAction>(8, this->action);
buffer.encode_enum<enums::ClimateFanMode>(9, this->fan_mode);
buffer.encode_enum<enums::ClimateSwingMode>(10, this->swing_mode);
@@ -3724,8 +3769,8 @@ void ClimateStateResponse::dump_to(std::string &out) const {
out.append(buffer);
out.append("\n");
out.append(" legacy_away: ");
out.append(YESNO(this->legacy_away));
out.append(" unused_legacy_away: ");
out.append(YESNO(this->unused_legacy_away));
out.append("\n");
out.append(" action: ");
@@ -3777,11 +3822,11 @@ bool ClimateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value)
return true;
}
case 10: {
this->has_legacy_away = value.as_bool();
this->unused_has_legacy_away = value.as_bool();
return true;
}
case 11: {
this->legacy_away = value.as_bool();
this->unused_legacy_away = value.as_bool();
return true;
}
case 12: {
@@ -3866,8 +3911,8 @@ void ClimateCommandRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_float(7, this->target_temperature_low);
buffer.encode_bool(8, this->has_target_temperature_high);
buffer.encode_float(9, this->target_temperature_high);
buffer.encode_bool(10, this->has_legacy_away);
buffer.encode_bool(11, this->legacy_away);
buffer.encode_bool(10, this->unused_has_legacy_away);
buffer.encode_bool(11, this->unused_legacy_away);
buffer.encode_bool(12, this->has_fan_mode);
buffer.encode_enum<enums::ClimateFanMode>(13, this->fan_mode);
buffer.encode_bool(14, this->has_swing_mode);
@@ -3923,12 +3968,12 @@ void ClimateCommandRequest::dump_to(std::string &out) const {
out.append(buffer);
out.append("\n");
out.append(" has_legacy_away: ");
out.append(YESNO(this->has_legacy_away));
out.append(" unused_has_legacy_away: ");
out.append(YESNO(this->unused_has_legacy_away));
out.append("\n");
out.append(" legacy_away: ");
out.append(YESNO(this->legacy_away));
out.append(" unused_legacy_away: ");
out.append(YESNO(this->unused_legacy_away));
out.append("\n");
out.append(" has_fan_mode: ");
@@ -6062,6 +6107,12 @@ void BluetoothDeviceUnpairingResponse::dump_to(std::string &out) const {
out.append("}");
}
#endif
void UnsubscribeBluetoothLEAdvertisementsRequest::encode(ProtoWriteBuffer buffer) const {}
#ifdef HAS_PROTO_MESSAGE_DUMP
void UnsubscribeBluetoothLEAdvertisementsRequest::dump_to(std::string &out) const {
out.append("UnsubscribeBluetoothLEAdvertisementsRequest {}");
}
#endif
bool BluetoothDeviceClearCacheResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
@@ -6105,6 +6156,155 @@ void BluetoothDeviceClearCacheResponse::dump_to(std::string &out) const {
out.append("}");
}
#endif
bool SubscribeVoiceAssistantRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->subscribe = value.as_bool();
return true;
}
default:
return false;
}
}
void SubscribeVoiceAssistantRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->subscribe); }
#ifdef HAS_PROTO_MESSAGE_DUMP
void SubscribeVoiceAssistantRequest::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("SubscribeVoiceAssistantRequest {\n");
out.append(" subscribe: ");
out.append(YESNO(this->subscribe));
out.append("\n");
out.append("}");
}
#endif
bool VoiceAssistantRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->start = value.as_bool();
return true;
}
default:
return false;
}
}
void VoiceAssistantRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->start); }
#ifdef HAS_PROTO_MESSAGE_DUMP
void VoiceAssistantRequest::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("VoiceAssistantRequest {\n");
out.append(" start: ");
out.append(YESNO(this->start));
out.append("\n");
out.append("}");
}
#endif
bool VoiceAssistantResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->port = value.as_uint32();
return true;
}
case 2: {
this->error = value.as_bool();
return true;
}
default:
return false;
}
}
void VoiceAssistantResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, this->port);
buffer.encode_bool(2, this->error);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void VoiceAssistantResponse::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("VoiceAssistantResponse {\n");
out.append(" port: ");
sprintf(buffer, "%u", this->port);
out.append(buffer);
out.append("\n");
out.append(" error: ");
out.append(YESNO(this->error));
out.append("\n");
out.append("}");
}
#endif
bool VoiceAssistantEventData::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 1: {
this->name = value.as_string();
return true;
}
case 2: {
this->value = value.as_string();
return true;
}
default:
return false;
}
}
void VoiceAssistantEventData::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->name);
buffer.encode_string(2, this->value);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void VoiceAssistantEventData::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("VoiceAssistantEventData {\n");
out.append(" name: ");
out.append("'").append(this->name).append("'");
out.append("\n");
out.append(" value: ");
out.append("'").append(this->value).append("'");
out.append("\n");
out.append("}");
}
#endif
bool VoiceAssistantEventResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->event_type = value.as_enum<enums::VoiceAssistantEvent>();
return true;
}
default:
return false;
}
}
bool VoiceAssistantEventResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 2: {
this->data.push_back(value.as_message<VoiceAssistantEventData>());
return true;
}
default:
return false;
}
}
void VoiceAssistantEventResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_enum<enums::VoiceAssistantEvent>(1, this->event_type);
for (auto &it : this->data) {
buffer.encode_message<VoiceAssistantEventData>(2, it, true);
}
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void VoiceAssistantEventResponse::dump_to(std::string &out) const {
__attribute__((unused)) char buffer[64];
out.append("VoiceAssistantEventResponse {\n");
out.append(" event_type: ");
out.append(proto_enum_to_string<enums::VoiceAssistantEvent>(this->event_type));
out.append("\n");
for (const auto &it : this->data) {
out.append(" data: ");
it.dump_to(out);
out.append("\n");
}
out.append("}");
}
#endif
} // namespace api
} // namespace esphome

View File

@@ -165,6 +165,17 @@ enum BluetoothDeviceRequestType : uint32_t {
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5,
BLUETOOTH_DEVICE_REQUEST_TYPE_CLEAR_CACHE = 6,
};
enum VoiceAssistantEvent : uint32_t {
VOICE_ASSISTANT_ERROR = 0,
VOICE_ASSISTANT_RUN_START = 1,
VOICE_ASSISTANT_RUN_END = 2,
VOICE_ASSISTANT_STT_START = 3,
VOICE_ASSISTANT_STT_END = 4,
VOICE_ASSISTANT_INTENT_START = 5,
VOICE_ASSISTANT_INTENT_END = 6,
VOICE_ASSISTANT_TTS_START = 7,
VOICE_ASSISTANT_TTS_END = 8,
};
} // namespace enums
@@ -279,6 +290,7 @@ class DeviceInfoResponse : public ProtoMessage {
uint32_t bluetooth_proxy_version{0};
std::string manufacturer{};
std::string friendly_name{};
uint32_t voice_assistant_version{0};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
@@ -363,6 +375,7 @@ class ListEntitiesCoverResponse : public ProtoMessage {
bool disabled_by_default{false};
std::string icon{};
enums::EntityCategory entity_category{};
bool supports_stop{false};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;
@@ -946,7 +959,7 @@ class ClimateStateResponse : public ProtoMessage {
float target_temperature{0.0f};
float target_temperature_low{0.0f};
float target_temperature_high{0.0f};
bool legacy_away{false};
bool unused_legacy_away{false};
enums::ClimateAction action{};
enums::ClimateFanMode fan_mode{};
enums::ClimateSwingMode swing_mode{};
@@ -974,8 +987,8 @@ class ClimateCommandRequest : public ProtoMessage {
float target_temperature_low{0.0f};
bool has_target_temperature_high{false};
float target_temperature_high{0.0f};
bool has_legacy_away{false};
bool legacy_away{false};
bool unused_has_legacy_away{false};
bool unused_legacy_away{false};
bool has_fan_mode{false};
enums::ClimateFanMode fan_mode{};
bool has_swing_mode{false};
@@ -1555,6 +1568,15 @@ class BluetoothDeviceUnpairingResponse : public ProtoMessage {
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class UnsubscribeBluetoothLEAdvertisementsRequest : 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 BluetoothDeviceClearCacheResponse : public ProtoMessage {
public:
uint64_t address{0};
@@ -1568,6 +1590,65 @@ class BluetoothDeviceClearCacheResponse : public ProtoMessage {
protected:
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class SubscribeVoiceAssistantRequest : public ProtoMessage {
public:
bool subscribe{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 VoiceAssistantRequest : public ProtoMessage {
public:
bool start{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 VoiceAssistantResponse : public ProtoMessage {
public:
uint32_t port{0};
bool error{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 VoiceAssistantEventData : public ProtoMessage {
public:
std::string name{};
std::string value{};
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;
};
class VoiceAssistantEventResponse : public ProtoMessage {
public:
enums::VoiceAssistantEvent event_type{};
std::vector<VoiceAssistantEventData> 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;
};
} // namespace api
} // namespace esphome

View File

@@ -329,6 +329,8 @@ bool APIServerConnectionBase::send_media_player_state_response(const MediaPlayer
#ifdef USE_MEDIA_PLAYER
#endif
#ifdef USE_BLUETOOTH_PROXY
#endif
#ifdef USE_BLUETOOTH_PROXY
bool APIServerConnectionBase::send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg) {
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "send_bluetooth_le_advertisement_response: %s", msg.dump().c_str());
@@ -442,6 +444,8 @@ bool APIServerConnectionBase::send_bluetooth_device_unpairing_response(const Blu
}
#endif
#ifdef USE_BLUETOOTH_PROXY
#endif
#ifdef USE_BLUETOOTH_PROXY
bool APIServerConnectionBase::send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg) {
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "send_bluetooth_device_clear_cache_response: %s", msg.dump().c_str());
@@ -449,6 +453,20 @@ bool APIServerConnectionBase::send_bluetooth_device_clear_cache_response(const B
return this->send_message_<BluetoothDeviceClearCacheResponse>(msg, 88);
}
#endif
#ifdef USE_VOICE_ASSISTANT
#endif
#ifdef USE_VOICE_ASSISTANT
bool APIServerConnectionBase::send_voice_assistant_request(const VoiceAssistantRequest &msg) {
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "send_voice_assistant_request: %s", msg.dump().c_str());
#endif
return this->send_message_<VoiceAssistantRequest>(msg, 90);
}
#endif
#ifdef USE_VOICE_ASSISTANT
#endif
#ifdef USE_VOICE_ASSISTANT
#endif
bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
switch (msg_type) {
case 1: {
@@ -717,12 +735,14 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
break;
}
case 66: {
#ifdef USE_BLUETOOTH_PROXY
SubscribeBluetoothLEAdvertisementsRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
#endif
this->on_subscribe_bluetooth_le_advertisements_request(msg);
#endif
break;
}
case 68: {
@@ -810,6 +830,50 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
ESP_LOGVV(TAG, "on_subscribe_bluetooth_connections_free_request: %s", msg.dump().c_str());
#endif
this->on_subscribe_bluetooth_connections_free_request(msg);
#endif
break;
}
case 87: {
#ifdef USE_BLUETOOTH_PROXY
UnsubscribeBluetoothLEAdvertisementsRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_unsubscribe_bluetooth_le_advertisements_request: %s", msg.dump().c_str());
#endif
this->on_unsubscribe_bluetooth_le_advertisements_request(msg);
#endif
break;
}
case 89: {
#ifdef USE_VOICE_ASSISTANT
SubscribeVoiceAssistantRequest msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_subscribe_voice_assistant_request: %s", msg.dump().c_str());
#endif
this->on_subscribe_voice_assistant_request(msg);
#endif
break;
}
case 91: {
#ifdef USE_VOICE_ASSISTANT
VoiceAssistantResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_response: %s", msg.dump().c_str());
#endif
this->on_voice_assistant_response(msg);
#endif
break;
}
case 92: {
#ifdef USE_VOICE_ASSISTANT
VoiceAssistantEventResponse msg;
msg.decode(msg_data, msg_size);
#ifdef HAS_PROTO_MESSAGE_DUMP
ESP_LOGVV(TAG, "on_voice_assistant_event_response: %s", msg.dump().c_str());
#endif
this->on_voice_assistant_event_response(msg);
#endif
break;
}
@@ -1073,6 +1137,7 @@ void APIServerConnection::on_media_player_command_request(const MediaPlayerComma
this->media_player_command(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(
const SubscribeBluetoothLEAdvertisementsRequest &msg) {
if (!this->is_connection_setup()) {
@@ -1085,6 +1150,7 @@ void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(
}
this->subscribe_bluetooth_le_advertisements(msg);
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_bluetooth_device_request(const BluetoothDeviceRequest &msg) {
if (!this->is_connection_setup()) {
@@ -1193,6 +1259,33 @@ void APIServerConnection::on_subscribe_bluetooth_connections_free_request(
}
}
#endif
#ifdef USE_BLUETOOTH_PROXY
void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request(
const UnsubscribeBluetoothLEAdvertisementsRequest &msg) {
if (!this->is_connection_setup()) {
this->on_no_setup_connection();
return;
}
if (!this->is_authenticated()) {
this->on_unauthenticated_access();
return;
}
this->unsubscribe_bluetooth_le_advertisements(msg);
}
#endif
#ifdef USE_VOICE_ASSISTANT
void APIServerConnection::on_subscribe_voice_assistant_request(const SubscribeVoiceAssistantRequest &msg) {
if (!this->is_connection_setup()) {
this->on_no_setup_connection();
return;
}
if (!this->is_authenticated()) {
this->on_unauthenticated_access();
return;
}
this->subscribe_voice_assistant(msg);
}
#endif
} // namespace api
} // namespace esphome

View File

@@ -154,8 +154,10 @@ class APIServerConnectionBase : public ProtoService {
#ifdef USE_MEDIA_PLAYER
virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){};
#endif
#ifdef USE_BLUETOOTH_PROXY
virtual void on_subscribe_bluetooth_le_advertisements_request(
const SubscribeBluetoothLEAdvertisementsRequest &value){};
#endif
#ifdef USE_BLUETOOTH_PROXY
bool send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg);
#endif
@@ -216,8 +218,24 @@ class APIServerConnectionBase : public ProtoService {
#ifdef USE_BLUETOOTH_PROXY
bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg);
#endif
#ifdef USE_BLUETOOTH_PROXY
virtual void on_unsubscribe_bluetooth_le_advertisements_request(
const UnsubscribeBluetoothLEAdvertisementsRequest &value){};
#endif
#ifdef USE_BLUETOOTH_PROXY
bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg);
#endif
#ifdef USE_VOICE_ASSISTANT
virtual void on_subscribe_voice_assistant_request(const SubscribeVoiceAssistantRequest &value){};
#endif
#ifdef USE_VOICE_ASSISTANT
bool send_voice_assistant_request(const VoiceAssistantRequest &msg);
#endif
#ifdef USE_VOICE_ASSISTANT
virtual void on_voice_assistant_response(const VoiceAssistantResponse &value){};
#endif
#ifdef USE_VOICE_ASSISTANT
virtual void on_voice_assistant_event_response(const VoiceAssistantEventResponse &value){};
#endif
protected:
bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
@@ -270,7 +288,9 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_MEDIA_PLAYER
virtual void media_player_command(const MediaPlayerCommandRequest &msg) = 0;
#endif
#ifdef USE_BLUETOOTH_PROXY
virtual void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) = 0;
#endif
#ifdef USE_BLUETOOTH_PROXY
virtual void bluetooth_device_request(const BluetoothDeviceRequest &msg) = 0;
#endif
@@ -295,6 +315,12 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_BLUETOOTH_PROXY
virtual BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(
const SubscribeBluetoothConnectionsFreeRequest &msg) = 0;
#endif
#ifdef USE_BLUETOOTH_PROXY
virtual void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) = 0;
#endif
#ifdef USE_VOICE_ASSISTANT
virtual void subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) = 0;
#endif
protected:
void on_hello_request(const HelloRequest &msg) override;
@@ -342,7 +368,9 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_MEDIA_PLAYER
void on_media_player_command_request(const MediaPlayerCommandRequest &msg) override;
#endif
#ifdef USE_BLUETOOTH_PROXY
void on_subscribe_bluetooth_le_advertisements_request(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
#endif
#ifdef USE_BLUETOOTH_PROXY
void on_bluetooth_device_request(const BluetoothDeviceRequest &msg) override;
#endif
@@ -367,6 +395,13 @@ class APIServerConnection : public APIServerConnectionBase {
#ifdef USE_BLUETOOTH_PROXY
void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) override;
#endif
#ifdef USE_BLUETOOTH_PROXY
void on_unsubscribe_bluetooth_le_advertisements_request(
const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override;
#endif
#ifdef USE_VOICE_ASSISTANT
void on_subscribe_voice_assistant_request(const SubscribeVoiceAssistantRequest &msg) override;
#endif
};
} // namespace api

View File

@@ -427,5 +427,21 @@ void APIServer::on_shutdown() {
delay(10);
}
#ifdef USE_VOICE_ASSISTANT
bool APIServer::start_voice_assistant() {
for (auto &c : this->clients_) {
if (c->request_voice_assistant(true))
return true;
}
return false;
}
void APIServer::stop_voice_assistant() {
for (auto &c : this->clients_) {
if (c->request_voice_assistant(false))
return;
}
}
#endif
} // namespace api
} // namespace esphome

View File

@@ -95,6 +95,11 @@ class APIServer : public Component, public Controller {
void request_time();
#endif
#ifdef USE_VOICE_ASSISTANT
bool start_voice_assistant();
void stop_voice_assistant();
#endif
bool is_connected() const;
struct HomeAssistantStateSubscription {

View File

@@ -1,4 +1,5 @@
#include "proto.h"
#include <cinttypes>
#include "esphome/core/log.h"
namespace esphome {
@@ -13,7 +14,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
uint32_t consumed;
auto res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
if (!res.has_value()) {
ESP_LOGV(TAG, "Invalid field start at %u", i);
ESP_LOGV(TAG, "Invalid field start at %" PRIu32, i);
break;
}
@@ -25,12 +26,12 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
case 0: { // VarInt
res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
if (!res.has_value()) {
ESP_LOGV(TAG, "Invalid VarInt at %u", i);
ESP_LOGV(TAG, "Invalid VarInt at %" PRIu32, i);
error = true;
break;
}
if (!this->decode_varint(field_id, *res)) {
ESP_LOGV(TAG, "Cannot decode VarInt field %u with value %u!", field_id, res->as_uint32());
ESP_LOGV(TAG, "Cannot decode VarInt field %" PRIu32 " with value %" PRIu32 "!", field_id, res->as_uint32());
}
i += consumed;
break;
@@ -38,38 +39,38 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
case 2: { // Length-delimited
res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
if (!res.has_value()) {
ESP_LOGV(TAG, "Invalid Length Delimited at %u", i);
ESP_LOGV(TAG, "Invalid Length Delimited at %" PRIu32, i);
error = true;
break;
}
uint32_t field_length = res->as_uint32();
i += consumed;
if (field_length > length - i) {
ESP_LOGV(TAG, "Out-of-bounds Length Delimited at %u", i);
ESP_LOGV(TAG, "Out-of-bounds Length Delimited at %" PRIu32, i);
error = true;
break;
}
if (!this->decode_length(field_id, ProtoLengthDelimited(&buffer[i], field_length))) {
ESP_LOGV(TAG, "Cannot decode Length Delimited field %u!", field_id);
ESP_LOGV(TAG, "Cannot decode Length Delimited field %" PRIu32 "!", field_id);
}
i += field_length;
break;
}
case 5: { // 32-bit
if (length - i < 4) {
ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at %u", i);
ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at %" PRIu32, i);
error = true;
break;
}
uint32_t val = encode_uint32(buffer[i + 3], buffer[i + 2], buffer[i + 1], buffer[i]);
if (!this->decode_32bit(field_id, Proto32Bit(val))) {
ESP_LOGV(TAG, "Cannot decode 32-bit field %u with value %u!", field_id, val);
ESP_LOGV(TAG, "Cannot decode 32-bit field %" PRIu32 " with value %" PRIu32 "!", field_id, val);
}
i += 4;
break;
}
default:
ESP_LOGV(TAG, "Invalid field type at %u", i);
ESP_LOGV(TAG, "Invalid field type at %" PRIu32, i);
error = true;
break;
}

View File

@@ -12,7 +12,6 @@ from esphome.const import (
CONF_CAPACITANCE,
)
AUTO_LOAD = ["sensor", "binary_sensor"]
MULTI_CONF = True
CONF_AS3935_ID = "as3935_id"

View File

@@ -26,9 +26,13 @@ void AS3935Component::setup() {
void AS3935Component::dump_config() {
ESP_LOGCONFIG(TAG, "AS3935:");
LOG_PIN(" Interrupt Pin: ", this->irq_pin_);
#ifdef USE_BINARY_SENSOR
LOG_BINARY_SENSOR(" ", "Thunder alert", this->thunder_alert_binary_sensor_);
#endif
#ifdef USE_SENSOR
LOG_SENSOR(" ", "Distance", this->distance_sensor_);
LOG_SENSOR(" ", "Lightning energy", this->energy_sensor_);
#endif
}
float AS3935Component::get_setup_priority() const { return setup_priority::DATA; }
@@ -44,16 +48,22 @@ void AS3935Component::loop() {
ESP_LOGI(TAG, "Disturber was detected - try increasing the spike rejection value!");
} else if (int_value == LIGHTNING_INT) {
ESP_LOGI(TAG, "Lightning has been detected!");
if (this->thunder_alert_binary_sensor_ != nullptr)
#ifdef USE_BINARY_SENSOR
if (this->thunder_alert_binary_sensor_ != nullptr) {
this->thunder_alert_binary_sensor_->publish_state(true);
this->set_timeout(10, [this]() { this->thunder_alert_binary_sensor_->publish_state(false); });
}
#endif
#ifdef USE_SENSOR
uint8_t distance = this->get_distance_to_storm_();
if (this->distance_sensor_ != nullptr)
this->distance_sensor_->publish_state(distance);
uint32_t energy = this->get_lightning_energy_();
if (this->energy_sensor_ != nullptr)
this->energy_sensor_->publish_state(energy);
#endif
}
this->thunder_alert_binary_sensor_->publish_state(false);
}
void AS3935Component::write_indoor(bool indoor) {

View File

@@ -1,9 +1,14 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#include "esphome/core/hal.h"
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
namespace esphome {
namespace as3935 {
@@ -52,6 +57,15 @@ enum AS3935Values {
};
class AS3935Component : public Component {
#ifdef USE_SENSOR
SUB_SENSOR(distance)
SUB_SENSOR(energy)
#endif
#ifdef USE_BINARY_SENSOR
SUB_BINARY_SENSOR(thunder_alert)
#endif
public:
void setup() override;
void dump_config() override;
@@ -59,11 +73,7 @@ class AS3935Component : public Component {
void loop() override;
void set_irq_pin(GPIOPin *irq_pin) { irq_pin_ = irq_pin; }
void set_distance_sensor(sensor::Sensor *distance_sensor) { distance_sensor_ = distance_sensor; }
void set_energy_sensor(sensor::Sensor *energy_sensor) { energy_sensor_ = energy_sensor; }
void set_thunder_alert_binary_sensor(binary_sensor::BinarySensor *thunder_alert_binary_sensor) {
thunder_alert_binary_sensor_ = thunder_alert_binary_sensor;
}
void set_indoor(bool indoor) { indoor_ = indoor; }
void write_indoor(bool indoor);
void set_noise_level(uint8_t noise_level) { noise_level_ = noise_level; }
@@ -92,9 +102,6 @@ class AS3935Component : public Component {
virtual void write_register(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position) = 0;
sensor::Sensor *distance_sensor_{nullptr};
sensor::Sensor *energy_sensor_{nullptr};
binary_sensor::BinarySensor *thunder_alert_binary_sensor_{nullptr};
GPIOPin *irq_pin_;
bool indoor_;

View File

@@ -18,5 +18,5 @@ async def to_code(config):
# https://github.com/esphome/AsyncTCP/blob/master/library.json
cg.add_library("esphome/AsyncTCP-esphome", "1.2.2")
elif CORE.is_esp8266:
# https://github.com/OttoWinter/ESPAsyncTCP
cg.add_library("ottowinter/ESPAsyncTCP-esphome", "1.2.3")
# https://github.com/esphome/ESPAsyncTCP
cg.add_library("esphome/ESPAsyncTCP-esphome", "1.2.3")

View File

@@ -116,7 +116,7 @@ class BedJetHub : public esphome::ble_client::BLEClientNode, public PollingCompo
void update() override;
void dump_config() override;
void setup() override { this->codec_ = make_unique<BedjetCodec>(); }
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
float get_setup_priority() const override { return setup_priority::BLUETOOTH; }
/** @return The BedJet's configured name, or the MAC address if not discovered yet. */
std::string get_name() {

View File

@@ -43,12 +43,7 @@ void BinarySensor::send_state_internal(bool state, bool is_initial) {
}
BinarySensor::BinarySensor() : state(false) {}
void BinarySensor::set_device_class(const std::string &device_class) { this->device_class_ = device_class; }
std::string BinarySensor::get_device_class() {
if (this->device_class_.has_value())
return *this->device_class_;
return "";
}
void BinarySensor::add_filter(Filter *filter) {
filter->parent_ = this;
if (this->filter_list_ == nullptr) {

View File

@@ -34,7 +34,7 @@ namespace binary_sensor {
* The sub classes should notify the front-end of new states via the publish_state() method which
* handles inverted inputs for you.
*/
class BinarySensor : public EntityBase {
class BinarySensor : public EntityBase, public EntityBase_DeviceClass {
public:
explicit BinarySensor();
@@ -60,12 +60,6 @@ class BinarySensor : public EntityBase {
/// The current reported state of the binary sensor.
bool state;
/// Manually set the Home Assistant device class (see binary_sensor::device_class)
void set_device_class(const std::string &device_class);
/// Get the device class for this binary sensor, using the manual override if specified.
std::string get_device_class();
void add_filter(Filter *filter);
void add_filters(const std::vector<Filter *> &filters);
@@ -82,7 +76,6 @@ class BinarySensor : public EntityBase {
protected:
CallbackManager<void(bool)> state_callback_{};
optional<std::string> device_class_{}; ///< Stores the override of the device class
Filter *filter_list_{nullptr};
bool has_state_{false};
bool publish_initial_state_{false};

View File

@@ -16,6 +16,9 @@ void BinarySensorMap::loop() {
case BINARY_SENSOR_MAP_TYPE_SUM:
this->process_sum_();
break;
case BINARY_SENSOR_MAP_TYPE_BAYESIAN:
this->process_bayesian_();
break;
}
}
@@ -23,69 +26,117 @@ void BinarySensorMap::process_group_() {
float total_current_value = 0.0;
uint8_t num_active_sensors = 0;
uint64_t mask = 0x00;
// check all binary_sensors for its state. when active add its value to total_current_value.
// create a bitmask for the binary_sensor status on all channels
// - check all binary_sensors for its state
// - if active, add its value to total_current_value.
// - creates a bitmask for the binary_sensor states on all channels
for (size_t i = 0; i < this->channels_.size(); i++) {
auto bs = this->channels_[i];
if (bs.binary_sensor->state) {
num_active_sensors++;
total_current_value += bs.sensor_value;
mask |= 1 << i;
total_current_value += bs.parameters.sensor_value;
mask |= 1ULL << i;
}
}
// check if the sensor map was touched
// potentially update state only if a binary_sensor is active
if (mask != 0ULL) {
// did the bit_mask change or is it a new sensor touch
// publish the average if the bitmask has changed
if (this->last_mask_ != mask) {
float publish_value = total_current_value / num_active_sensors;
ESP_LOGD(TAG, "'%s' - Publishing %.2f", this->name_.c_str(), publish_value);
this->publish_state(publish_value);
}
} else if (this->last_mask_ != 0ULL) {
// is this a new sensor release
ESP_LOGD(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str());
// no buttons are pressed and the states have changed since last run, so publish NAN
ESP_LOGV(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str());
this->publish_state(NAN);
}
this->last_mask_ = mask;
}
void BinarySensorMap::process_sum_() {
float total_current_value = 0.0;
uint64_t mask = 0x00;
// check all binary_sensors for its state. when active add its value to total_current_value.
// create a bitmask for the binary_sensor status on all channels
// - check all binary_sensor states
// - if active, add its value to total_current_value
// - creates a bitmask for the binary_sensor states on all channels
for (size_t i = 0; i < this->channels_.size(); i++) {
auto bs = this->channels_[i];
if (bs.binary_sensor->state) {
total_current_value += bs.sensor_value;
mask |= 1 << i;
total_current_value += bs.parameters.sensor_value;
mask |= 1ULL << i;
}
}
// check if the sensor map was touched
if (mask != 0ULL) {
// did the bit_mask change or is it a new sensor touch
if (this->last_mask_ != mask) {
float publish_value = total_current_value;
ESP_LOGD(TAG, "'%s' - Publishing %.2f", this->name_.c_str(), publish_value);
this->publish_state(publish_value);
}
} else if (this->last_mask_ != 0ULL) {
// is this a new sensor release
ESP_LOGD(TAG, "'%s' - No binary sensor active, publishing 0", this->name_.c_str());
this->publish_state(0.0);
// update state only if any binary_sensor states have changed or if no state has ever been sent on boot
if ((this->last_mask_ != mask) || (!this->has_state())) {
this->publish_state(total_current_value);
}
this->last_mask_ = mask;
}
void BinarySensorMap::process_bayesian_() {
float posterior_probability = this->bayesian_prior_;
uint64_t mask = 0x00;
// - compute the posterior probability by taking the product of the predicate probablities for each observation
// - create a bitmask for the binary_sensor states on all channels/observations
for (size_t i = 0; i < this->channels_.size(); i++) {
auto bs = this->channels_[i];
posterior_probability *=
this->bayesian_predicate_(bs.binary_sensor->state, posterior_probability,
bs.parameters.probabilities.given_true, bs.parameters.probabilities.given_false);
mask |= ((uint64_t) (bs.binary_sensor->state)) << i;
}
// update state only if any binary_sensor states have changed or if no state has ever been sent on boot
if ((this->last_mask_ != mask) || (!this->has_state())) {
this->publish_state(posterior_probability);
}
this->last_mask_ = mask;
}
float BinarySensorMap::bayesian_predicate_(bool sensor_state, float prior, float prob_given_true,
float prob_given_false) {
float prob_state_source_true = prob_given_true;
float prob_state_source_false = prob_given_false;
// if sensor is off, then we use the probabilities for the observation's complement
if (!sensor_state) {
prob_state_source_true = 1 - prob_given_true;
prob_state_source_false = 1 - prob_given_false;
}
return prob_state_source_true / (prior * prob_state_source_true + (1.0 - prior) * prob_state_source_false);
}
void BinarySensorMap::add_channel(binary_sensor::BinarySensor *sensor, float value) {
BinarySensorMapChannel sensor_channel{
.binary_sensor = sensor,
.sensor_value = value,
.parameters{
.sensor_value = value,
},
};
this->channels_.push_back(sensor_channel);
}
void BinarySensorMap::set_sensor_type(BinarySensorMapType sensor_type) { this->sensor_type_ = sensor_type; }
void BinarySensorMap::add_channel(binary_sensor::BinarySensor *sensor, float prob_given_true, float prob_given_false) {
BinarySensorMapChannel sensor_channel{
.binary_sensor = sensor,
.parameters{
.probabilities{
.given_true = prob_given_true,
.given_false = prob_given_false,
},
},
};
this->channels_.push_back(sensor_channel);
}
} // namespace binary_sensor_map
} // namespace esphome

View File

@@ -12,51 +12,88 @@ namespace binary_sensor_map {
enum BinarySensorMapType {
BINARY_SENSOR_MAP_TYPE_GROUP,
BINARY_SENSOR_MAP_TYPE_SUM,
BINARY_SENSOR_MAP_TYPE_BAYESIAN,
};
struct BinarySensorMapChannel {
binary_sensor::BinarySensor *binary_sensor;
float sensor_value;
union {
float sensor_value;
struct {
float given_true;
float given_false;
} probabilities;
} parameters;
};
/** Class to group binary_sensors to one Sensor.
/** Class to map one or more binary_sensors to one Sensor.
*
* Each binary sensor represents a float value in the group.
* Each binary sensor has configured parameters that each mapping type uses to compute the single numerical result
*/
class BinarySensorMap : public sensor::Sensor, public Component {
public:
void dump_config() override;
/**
* The loop checks all binary_sensor states
* When the binary_sensor reports a true value for its state, then the float value it represents is added to the
* total_current_value
* The loop calls the configured type processing method
*
* Only when the total_current_value changed and at least one sensor reports an active state we publish the sensors
* average value. When the value changed and no sensors ar active we publish NAN.
* */
* The processing method loops through all sensors and calculates the numerical result
* The result is only published if a binary sensor state has changed or, for some types, on initial boot
*/
void loop() override;
float get_setup_priority() const override { return setup_priority::DATA; }
/** Add binary_sensors to the group.
* Each binary_sensor represents a float value when its state is true
/**
* Add binary_sensors to the group when only one parameter is needed for the configured mapping type.
*
* @param *sensor The binary sensor.
* @param value The value this binary_sensor represents
*/
void add_channel(binary_sensor::BinarySensor *sensor, float value);
void set_sensor_type(BinarySensorMapType sensor_type);
/**
* Add binary_sensors to the group when two parameters are needed for the Bayesian mapping type.
*
* @param *sensor The binary sensor.
* @param prob_given_true Probability this observation is on when the Bayesian event is true
* @param prob_given_false Probability this observation is on when the Bayesian event is false
*/
void add_channel(binary_sensor::BinarySensor *sensor, float prob_given_true, float prob_given_false);
void set_sensor_type(BinarySensorMapType sensor_type) { this->sensor_type_ = sensor_type; }
void set_bayesian_prior(float prior) { this->bayesian_prior_ = prior; };
protected:
std::vector<BinarySensorMapChannel> channels_{};
BinarySensorMapType sensor_type_{BINARY_SENSOR_MAP_TYPE_GROUP};
// this gives max 64 channels per binary_sensor_map
// this allows a max of 64 channels/observations in order to keep track of binary_sensor states
uint64_t last_mask_{0x00};
// Bayesian event prior probability before taking into account any observations
float bayesian_prior_{};
/**
* methods to process the types of binary_sensor_maps
* GROUP: process_group_() just map to a value
* Methods to process the binary_sensor_maps types
*
* GROUP: process_group_() averages all the values
* ADD: process_add_() adds all the values
* BAYESIAN: process_bayesian_() computes the predicate probability
* */
void process_group_();
void process_sum_();
void process_bayesian_();
/**
* Computes the Bayesian predicate for a specific observation
* If the sensor state is false, then we use the parameters' probabilities for the observatiosn complement
*
* @param sensor_state State of observation
* @param prior Prior probability before accounting for this observation
* @param prob_given_true Probability this observation is on when the Bayesian event is true
* @param prob_given_false Probability this observation is on when the Bayesian event is false
* */
float bayesian_predicate_(bool sensor_state, float prior, float prob_given_true, float prob_given_false);
};
} // namespace binary_sensor_map

View File

@@ -20,16 +20,29 @@ BinarySensorMap = binary_sensor_map_ns.class_(
)
SensorMapType = binary_sensor_map_ns.enum("SensorMapType")
CONF_BAYESIAN = "bayesian"
CONF_PRIOR = "prior"
CONF_PROB_GIVEN_TRUE = "prob_given_true"
CONF_PROB_GIVEN_FALSE = "prob_given_false"
CONF_OBSERVATIONS = "observations"
SENSOR_MAP_TYPES = {
CONF_GROUP: SensorMapType.BINARY_SENSOR_MAP_TYPE_GROUP,
CONF_SUM: SensorMapType.BINARY_SENSOR_MAP_TYPE_SUM,
CONF_BAYESIAN: SensorMapType.BINARY_SENSOR_MAP_TYPE_BAYESIAN,
}
entry = {
entry_one_parameter = {
cv.Required(CONF_BINARY_SENSOR): cv.use_id(binary_sensor.BinarySensor),
cv.Required(CONF_VALUE): cv.float_,
}
entry_bayesian_parameters = {
cv.Required(CONF_BINARY_SENSOR): cv.use_id(binary_sensor.BinarySensor),
cv.Required(CONF_PROB_GIVEN_TRUE): cv.float_range(min=0, max=1),
cv.Required(CONF_PROB_GIVEN_FALSE): cv.float_range(min=0, max=1),
}
CONFIG_SCHEMA = cv.typed_schema(
{
CONF_GROUP: sensor.sensor_schema(
@@ -39,7 +52,7 @@ CONFIG_SCHEMA = cv.typed_schema(
).extend(
{
cv.Required(CONF_CHANNELS): cv.All(
cv.ensure_list(entry), cv.Length(min=1)
cv.ensure_list(entry_one_parameter), cv.Length(min=1, max=64)
),
}
),
@@ -50,7 +63,18 @@ CONFIG_SCHEMA = cv.typed_schema(
).extend(
{
cv.Required(CONF_CHANNELS): cv.All(
cv.ensure_list(entry), cv.Length(min=1)
cv.ensure_list(entry_one_parameter), cv.Length(min=1, max=64)
),
}
),
CONF_BAYESIAN: sensor.sensor_schema(
BinarySensorMap,
accuracy_decimals=2,
).extend(
{
cv.Required(CONF_PRIOR): cv.float_range(min=0, max=1),
cv.Required(CONF_OBSERVATIONS): cv.All(
cv.ensure_list(entry_bayesian_parameters), cv.Length(min=1, max=64)
),
}
),
@@ -66,6 +90,17 @@ async def to_code(config):
constant = SENSOR_MAP_TYPES[config[CONF_TYPE]]
cg.add(var.set_sensor_type(constant))
for ch in config[CONF_CHANNELS]:
input_var = await cg.get_variable(ch[CONF_BINARY_SENSOR])
cg.add(var.add_channel(input_var, ch[CONF_VALUE]))
if config[CONF_TYPE] == CONF_BAYESIAN:
cg.add(var.set_bayesian_prior(config[CONF_PRIOR]))
for obs in config[CONF_OBSERVATIONS]:
input_var = await cg.get_variable(obs[CONF_BINARY_SENSOR])
cg.add(
var.add_channel(
input_var, obs[CONF_PROB_GIVEN_TRUE], obs[CONF_PROB_GIVEN_FALSE]
)
)
else:
for ch in config[CONF_CHANNELS]:
input_var = await cg.get_variable(ch[CONF_BINARY_SENSOR])
cg.add(var.add_channel(input_var, ch[CONF_VALUE]))

View File

@@ -29,8 +29,35 @@ BLEClientConnectTrigger = ble_client_ns.class_(
BLEClientDisconnectTrigger = ble_client_ns.class_(
"BLEClientDisconnectTrigger", automation.Trigger.template(BLEClientNodeConstRef)
)
BLEClientPasskeyRequestTrigger = ble_client_ns.class_(
"BLEClientPasskeyRequestTrigger", automation.Trigger.template(BLEClientNodeConstRef)
)
BLEClientPasskeyNotificationTrigger = ble_client_ns.class_(
"BLEClientPasskeyNotificationTrigger",
automation.Trigger.template(BLEClientNodeConstRef, cg.uint32),
)
BLEClientNumericComparisonRequestTrigger = ble_client_ns.class_(
"BLEClientNumericComparisonRequestTrigger",
automation.Trigger.template(BLEClientNodeConstRef, cg.uint32),
)
# Actions
BLEWriteAction = ble_client_ns.class_("BLEClientWriteAction", automation.Action)
BLEPasskeyReplyAction = ble_client_ns.class_(
"BLEClientPasskeyReplyAction", automation.Action
)
BLENumericComparisonReplyAction = ble_client_ns.class_(
"BLEClientNumericComparisonReplyAction", automation.Action
)
BLERemoveBondAction = ble_client_ns.class_(
"BLEClientRemoveBondAction", automation.Action
)
CONF_PASSKEY = "passkey"
CONF_ACCEPT = "accept"
CONF_ON_PASSKEY_REQUEST = "on_passkey_request"
CONF_ON_PASSKEY_NOTIFICATION = "on_passkey_notification"
CONF_ON_NUMERIC_COMPARISON_REQUEST = "on_numeric_comparison_request"
# Espressif platformio framework is built with MAX_BLE_CONN to 3, so
# enforce this in yaml checks.
@@ -56,6 +83,29 @@ CONFIG_SCHEMA = (
),
}
),
cv.Optional(CONF_ON_PASSKEY_REQUEST): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
BLEClientPasskeyRequestTrigger
),
}
),
cv.Optional(CONF_ON_PASSKEY_NOTIFICATION): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
BLEClientPasskeyNotificationTrigger
),
}
),
cv.Optional(
CONF_ON_NUMERIC_COMPARISON_REQUEST
): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
BLEClientNumericComparisonRequestTrigger
),
}
),
}
)
.extend(cv.COMPONENT_SCHEMA)
@@ -85,13 +135,34 @@ BLE_WRITE_ACTION_SCHEMA = cv.Schema(
}
)
BLE_NUMERIC_COMPARISON_REPLY_ACTION_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
cv.Required(CONF_ACCEPT): cv.templatable(cv.boolean),
}
)
BLE_PASSKEY_REPLY_ACTION_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
cv.Required(CONF_PASSKEY): cv.templatable(cv.int_range(min=0, max=999999)),
}
)
BLE_REMOVE_BOND_ACTION_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_ID): cv.use_id(BLEClient),
}
)
@automation.register_action(
"ble_client.ble_write", BLEWriteAction, BLE_WRITE_ACTION_SCHEMA
)
async def ble_write_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
parent = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, parent)
value = config[CONF_VALUE]
if cg.is_template(value):
@@ -137,6 +208,54 @@ async def ble_write_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
"ble_client.numeric_comparison_reply",
BLENumericComparisonReplyAction,
BLE_NUMERIC_COMPARISON_REPLY_ACTION_SCHEMA,
)
async def numeric_comparison_reply_to_code(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, parent)
accept = config[CONF_ACCEPT]
if cg.is_template(accept):
templ = await cg.templatable(accept, args, cg.bool_)
cg.add(var.set_value_template(templ))
else:
cg.add(var.set_value_simple(accept))
return var
@automation.register_action(
"ble_client.passkey_reply", BLEPasskeyReplyAction, BLE_PASSKEY_REPLY_ACTION_SCHEMA
)
async def passkey_reply_to_code(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, parent)
passkey = config[CONF_PASSKEY]
if cg.is_template(passkey):
templ = await cg.templatable(passkey, args, cg.uint32)
cg.add(var.set_value_template(templ))
else:
cg.add(var.set_value_simple(passkey))
return var
@automation.register_action(
"ble_client.remove_bond",
BLERemoveBondAction,
BLE_REMOVE_BOND_ACTION_SCHEMA,
)
async def remove_bond_to_code(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, parent)
return var
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
@@ -148,3 +267,12 @@ async def to_code(config):
for conf in config.get(CONF_ON_DISCONNECT, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
for conf in config.get(CONF_ON_PASSKEY_REQUEST, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
for conf in config.get(CONF_ON_PASSKEY_NOTIFICATION, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.uint32, "passkey")], conf)
for conf in config.get(CONF_ON_NUMERIC_COMPARISON_REQUEST, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.uint32, "passkey")], conf)

View File

@@ -37,6 +37,44 @@ class BLEClientDisconnectTrigger : public Trigger<>, public BLEClientNode {
}
};
class BLEClientPasskeyRequestTrigger : public Trigger<>, public BLEClientNode {
public:
explicit BLEClientPasskeyRequestTrigger(BLEClient *parent) { parent->register_ble_node(this); }
void loop() override {}
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override {
if (event == ESP_GAP_BLE_PASSKEY_REQ_EVT &&
memcmp(param->ble_security.auth_cmpl.bd_addr, this->parent_->get_remote_bda(), 6) == 0) {
this->trigger();
}
}
};
class BLEClientPasskeyNotificationTrigger : public Trigger<uint32_t>, public BLEClientNode {
public:
explicit BLEClientPasskeyNotificationTrigger(BLEClient *parent) { parent->register_ble_node(this); }
void loop() override {}
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override {
if (event == ESP_GAP_BLE_PASSKEY_NOTIF_EVT &&
memcmp(param->ble_security.auth_cmpl.bd_addr, this->parent_->get_remote_bda(), 6) == 0) {
uint32_t passkey = param->ble_security.key_notif.passkey;
this->trigger(passkey);
}
}
};
class BLEClientNumericComparisonRequestTrigger : public Trigger<uint32_t>, public BLEClientNode {
public:
explicit BLEClientNumericComparisonRequestTrigger(BLEClient *parent) { parent->register_ble_node(this); }
void loop() override {}
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override {
if (event == ESP_GAP_BLE_NC_REQ_EVT &&
memcmp(param->ble_security.auth_cmpl.bd_addr, this->parent_->get_remote_bda(), 6) == 0) {
uint32_t passkey = param->ble_security.key_notif.passkey;
this->trigger(passkey);
}
}
};
class BLEWriterClientNode : public BLEClientNode {
public:
BLEWriterClientNode(BLEClient *ble_client) {
@@ -94,6 +132,86 @@ template<typename... Ts> class BLEClientWriteAction : public Action<Ts...>, publ
std::function<std::vector<uint8_t>(Ts...)> value_template_{};
};
template<typename... Ts> class BLEClientPasskeyReplyAction : public Action<Ts...> {
public:
BLEClientPasskeyReplyAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override {
uint32_t passkey;
if (has_simple_value_) {
passkey = this->value_simple_;
} else {
passkey = this->value_template_(x...);
}
if (passkey > 999999)
return;
esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
esp_ble_passkey_reply(remote_bda, true, passkey);
}
void set_value_template(std::function<uint32_t(Ts...)> func) {
this->value_template_ = std::move(func);
has_simple_value_ = false;
}
void set_value_simple(const uint32_t &value) {
this->value_simple_ = value;
has_simple_value_ = true;
}
private:
BLEClient *parent_{nullptr};
bool has_simple_value_ = true;
uint32_t value_simple_{0};
std::function<uint32_t(Ts...)> value_template_{};
};
template<typename... Ts> class BLEClientNumericComparisonReplyAction : public Action<Ts...> {
public:
BLEClientNumericComparisonReplyAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override {
esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
if (has_simple_value_) {
esp_ble_confirm_reply(remote_bda, this->value_simple_);
} else {
esp_ble_confirm_reply(remote_bda, this->value_template_(x...));
}
}
void set_value_template(std::function<bool(Ts...)> func) {
this->value_template_ = std::move(func);
has_simple_value_ = false;
}
void set_value_simple(const bool &value) {
this->value_simple_ = value;
has_simple_value_ = true;
}
private:
BLEClient *parent_{nullptr};
bool has_simple_value_ = true;
bool value_simple_{false};
std::function<bool(Ts...)> value_template_{};
};
template<typename... Ts> class BLEClientRemoveBondAction : public Action<Ts...> {
public:
BLEClientRemoveBondAction(BLEClient *ble_client) { parent_ = ble_client; }
void play(Ts... x) override {
esp_bd_addr_t remote_bda;
memcpy(remote_bda, parent_->get_remote_bda(), sizeof(esp_bd_addr_t));
esp_ble_remove_bond_device(remote_bda);
}
private:
BLEClient *parent_{nullptr};
};
} // namespace ble_client
} // namespace esphome

View File

@@ -27,7 +27,7 @@ class BLEClient;
class BLEClientNode {
public:
virtual void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) = 0;
esp_ble_gattc_cb_param_t *param){};
virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {}
virtual void loop() {}
void set_address(uint64_t address) { address_ = address; }

View File

@@ -6,9 +6,6 @@ namespace button {
static const char *const TAG = "button";
Button::Button(const std::string &name) : EntityBase(name) {}
Button::Button() : Button("") {}
void Button::press() {
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
this->press_action();
@@ -16,8 +13,5 @@ void Button::press() {
}
void Button::add_on_press_callback(std::function<void()> &&callback) { this->press_callback_.add(std::move(callback)); }
void Button::set_device_class(const std::string &device_class) { this->device_class_ = device_class; }
std::string Button::get_device_class() { return this->device_class_; }
} // namespace button
} // namespace esphome

View File

@@ -26,11 +26,8 @@ namespace button {
*
* A button is just a momentary switch that does not have a state, only a trigger.
*/
class Button : public EntityBase {
class Button : public EntityBase, public EntityBase_DeviceClass {
public:
explicit Button();
explicit Button(const std::string &name);
/** Press this button. This is called by the front-end.
*
* For implementing buttons, please override press_action.
@@ -43,19 +40,12 @@ class Button : public EntityBase {
*/
void add_on_press_callback(std::function<void()> &&callback);
/// Set the Home Assistant device class (see button::device_class).
void set_device_class(const std::string &device_class);
/// Get the device class for this button.
std::string get_device_class();
protected:
/** You should implement this virtual method if you want to create your own button.
*/
virtual void press_action() = 0;
CallbackManager<void()> press_callback_{};
std::string device_class_{};
};
} // namespace button

View File

@@ -343,7 +343,7 @@ CLIMATE_CONTROL_ACTION_SCHEMA = cv.Schema(
cv.Optional(CONF_TARGET_TEMPERATURE): cv.templatable(cv.temperature),
cv.Optional(CONF_TARGET_TEMPERATURE_LOW): cv.templatable(cv.temperature),
cv.Optional(CONF_TARGET_TEMPERATURE_HIGH): cv.templatable(cv.temperature),
cv.Optional(CONF_AWAY): cv.templatable(cv.boolean),
cv.Optional(CONF_AWAY): cv.invalid("Use preset instead"),
cv.Exclusive(CONF_FAN_MODE, "fan_mode"): cv.templatable(
validate_climate_fan_mode
),
@@ -379,9 +379,6 @@ async def climate_control_to_code(config, action_id, template_arg, args):
config[CONF_TARGET_TEMPERATURE_HIGH], args, float
)
cg.add(var.set_target_temperature_high(template_))
if CONF_AWAY in config:
template_ = await cg.templatable(config[CONF_AWAY], args, bool)
cg.add(var.set_away(template_))
if CONF_FAN_MODE in config:
template_ = await cg.templatable(config[CONF_FAN_MODE], args, ClimateFanMode)
cg.add(var.set_fan_mode(template_))

View File

@@ -264,25 +264,11 @@ const optional<ClimateMode> &ClimateCall::get_mode() const { return this->mode_;
const optional<float> &ClimateCall::get_target_temperature() const { return this->target_temperature_; }
const optional<float> &ClimateCall::get_target_temperature_low() const { return this->target_temperature_low_; }
const optional<float> &ClimateCall::get_target_temperature_high() const { return this->target_temperature_high_; }
optional<bool> ClimateCall::get_away() const {
if (!this->preset_.has_value())
return {};
return *this->preset_ == ClimatePreset::CLIMATE_PRESET_AWAY;
}
const optional<ClimateFanMode> &ClimateCall::get_fan_mode() const { return this->fan_mode_; }
const optional<std::string> &ClimateCall::get_custom_fan_mode() const { return this->custom_fan_mode_; }
const optional<ClimatePreset> &ClimateCall::get_preset() const { return this->preset_; }
const optional<std::string> &ClimateCall::get_custom_preset() const { return this->custom_preset_; }
const optional<ClimateSwingMode> &ClimateCall::get_swing_mode() const { return this->swing_mode_; }
ClimateCall &ClimateCall::set_away(bool away) {
this->preset_ = away ? CLIMATE_PRESET_AWAY : CLIMATE_PRESET_HOME;
return *this;
}
ClimateCall &ClimateCall::set_away(optional<bool> away) {
if (away.has_value())
this->preset_ = *away ? CLIMATE_PRESET_AWAY : CLIMATE_PRESET_HOME;
return *this;
}
ClimateCall &ClimateCall::set_target_temperature_high(optional<float> target_temperature_high) {
this->target_temperature_high_ = target_temperature_high;
return *this;
@@ -453,12 +439,7 @@ void Climate::set_visual_temperature_step_override(float target, float current)
this->visual_target_temperature_step_override_ = target;
this->visual_current_temperature_step_override_ = current;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Climate::Climate(const std::string &name) : EntityBase(name) {}
#pragma GCC diagnostic pop
Climate::Climate() : Climate("") {}
ClimateCall Climate::make_call() { return ClimateCall(this); }
ClimateCall ClimateDeviceRestoreState::to_call(Climate *climate) {

View File

@@ -64,10 +64,6 @@ class ClimateCall {
* For climate devices with two point target temperature control
*/
ClimateCall &set_target_temperature_high(optional<float> target_temperature_high);
ESPDEPRECATED("set_away() is deprecated, please use .set_preset(CLIMATE_PRESET_AWAY) instead", "v1.20")
ClimateCall &set_away(bool away);
ESPDEPRECATED("set_away() is deprecated, please use .set_preset(CLIMATE_PRESET_AWAY) instead", "v1.20")
ClimateCall &set_away(optional<bool> away);
/// Set the fan mode of the climate device.
ClimateCall &set_fan_mode(ClimateFanMode fan_mode);
/// Set the fan mode of the climate device.
@@ -97,8 +93,6 @@ class ClimateCall {
const optional<float> &get_target_temperature() const;
const optional<float> &get_target_temperature_low() const;
const optional<float> &get_target_temperature_high() const;
ESPDEPRECATED("get_away() is deprecated, please use .get_preset() instead", "v1.20")
optional<bool> get_away() const;
const optional<ClimateFanMode> &get_fan_mode() const;
const optional<ClimateSwingMode> &get_swing_mode() const;
const optional<std::string> &get_custom_fan_mode() const;
@@ -166,11 +160,6 @@ struct ClimateDeviceRestoreState {
*/
class Climate : public EntityBase {
public:
/// Construct a climate device with empty name (will be set later).
Climate();
/// Construct a climate device with a name.
Climate(const std::string &name);
/// The active mode of the climate device.
ClimateMode mode{CLIMATE_MODE_OFF};
/// The active state of the climate device.
@@ -189,14 +178,6 @@ class Climate : public EntityBase {
};
};
/** Whether the climate device is in away mode.
*
* Away allows climate devices to have two different target temperature configs:
* one for normal mode and one for away mode.
*/
ESPDEPRECATED("away is deprecated, use preset instead", "v1.20")
bool away{false};
/// The active fan mode of the climate device.
optional<ClimateFanMode> fan_mode;

View File

@@ -117,15 +117,6 @@ class ClimateTraits {
bool supports_custom_preset(const std::string &custom_preset) const {
return supported_custom_presets_.count(custom_preset);
}
ESPDEPRECATED("This method is deprecated, use set_supported_presets() instead", "v1.20")
void set_supports_away(bool supports) {
if (supports) {
supported_presets_.insert(CLIMATE_PRESET_AWAY);
supported_presets_.insert(CLIMATE_PRESET_HOME);
}
}
ESPDEPRECATED("This method is deprecated, use supports_preset() instead", "v1.20")
bool get_supports_away() const { return supports_preset(CLIMATE_PRESET_AWAY); }
void set_supported_swing_modes(std::set<ClimateSwingMode> modes) { supported_swing_modes_ = std::move(modes); }
void add_supported_swing_mode(ClimateSwingMode mode) { supported_swing_modes_.insert(mode); }

View File

@@ -28,6 +28,7 @@ cover::CoverTraits CopyCover::get_traits() {
// copy traits manually so it doesn't break when new options are added
// but the control() method hasn't implemented them yet.
traits.set_is_assumed_state(base.get_is_assumed_state());
traits.set_supports_stop(base.get_supports_stop());
traits.set_supports_position(base.get_supports_position());
traits.set_supports_tilt(base.get_supports_tilt());
traits.set_supports_toggle(base.get_supports_toggle());

View File

@@ -31,7 +31,7 @@ const char *cover_operation_to_str(CoverOperation op) {
}
}
Cover::Cover(const std::string &name) : EntityBase(name), position{COVER_OPEN} {}
Cover::Cover() : position{COVER_OPEN} {}
CoverCall::CoverCall(Cover *parent) : parent_(parent) {}
CoverCall &CoverCall::set_command(const char *command) {
@@ -145,7 +145,7 @@ CoverCall &CoverCall::set_stop(bool stop) {
return *this;
}
bool CoverCall::get_stop() const { return this->stop_; }
void Cover::set_device_class(const std::string &device_class) { this->device_class_override_ = device_class; }
CoverCall Cover::make_call() { return {this}; }
void Cover::open() {
auto call = this->make_call();
@@ -204,12 +204,7 @@ optional<CoverRestoreState> Cover::restore_state_() {
return {};
return recovered;
}
Cover::Cover() : Cover("") {}
std::string Cover::get_device_class() {
if (this->device_class_override_.has_value())
return *this->device_class_override_;
return "";
}
bool Cover::is_fully_open() const { return this->position == COVER_OPEN; }
bool Cover::is_fully_closed() const { return this->position == COVER_CLOSED; }

View File

@@ -108,10 +108,9 @@ const char *cover_operation_to_str(CoverOperation op);
* to control all values of the cover. Also implement get_traits() to return what operations
* the cover supports.
*/
class Cover : public EntityBase {
class Cover : public EntityBase, public EntityBase_DeviceClass {
public:
explicit Cover();
explicit Cover(const std::string &name);
/// The current operation of the cover (idle, opening, closing).
CoverOperation current_operation{COVER_OPERATION_IDLE};
@@ -141,8 +140,9 @@ class Cover : public EntityBase {
/** Stop the cover.
*
* This is a legacy method and may be removed later, please use `.make_call()` instead.
* As per solution from issue #2885 the call should include perform()
*/
ESPDEPRECATED("stop() is deprecated, use make_call().set_command_stop() instead.", "2021.9")
ESPDEPRECATED("stop() is deprecated, use make_call().set_command_stop().perform() instead.", "2021.9")
void stop();
void add_on_state_callback(std::function<void()> &&f);
@@ -157,8 +157,6 @@ class Cover : public EntityBase {
void publish_state(bool save = true);
virtual CoverTraits get_traits() = 0;
void set_device_class(const std::string &device_class);
std::string get_device_class();
/// Helper method to check if the cover is fully open. Equivalent to comparing .position against 1.0
bool is_fully_open() const;
@@ -173,7 +171,6 @@ class Cover : public EntityBase {
optional<CoverRestoreState> restore_state_();
CallbackManager<void()> state_callback_{};
optional<std::string> device_class_override_{};
ESPPreferenceObject rtc_;
};

View File

@@ -15,12 +15,15 @@ class CoverTraits {
void set_supports_tilt(bool supports_tilt) { this->supports_tilt_ = supports_tilt; }
bool get_supports_toggle() const { return this->supports_toggle_; }
void set_supports_toggle(bool supports_toggle) { this->supports_toggle_ = supports_toggle; }
bool get_supports_stop() const { return this->supports_stop_; }
void set_supports_stop(bool supports_stop) { this->supports_stop_ = supports_stop; }
protected:
bool is_assumed_state_{false};
bool supports_position_{false};
bool supports_tilt_{false};
bool supports_toggle_{false};
bool supports_stop_{false};
};
} // namespace cover

View File

@@ -12,6 +12,7 @@ using namespace esphome::cover;
CoverTraits CurrentBasedCover::get_traits() {
auto traits = CoverTraits();
traits.set_supports_stop(true);
traits.set_supports_position(true);
traits.set_supports_toggle(true);
traits.set_is_assumed_state(false);

View File

@@ -7,9 +7,10 @@ import requests
import esphome.codegen as cg
import esphome.config_validation as cv
import esphome.final_validate as fv
from esphome import git
from esphome.components.packages import validate_source_shorthand
from esphome.const import CONF_REF, CONF_WIFI
from esphome.const import CONF_REF, CONF_WIFI, CONF_ESPHOME, CONF_PROJECT
from esphome.wizard import wizard_file
from esphome.yaml_util import dump
@@ -52,6 +53,17 @@ CONFIG_SCHEMA = cv.All(
validate_full_url,
)
def _final_validate(config):
full_config = fv.full_config.get()[CONF_ESPHOME]
if CONF_PROJECT not in full_config:
raise cv.Invalid(
"Dashboard import requires the `esphome` -> `project` information to be provided."
)
FINAL_VALIDATE_SCHEMA = _final_validate
WIFI_CONFIG = """
wifi:

View File

@@ -1,15 +1,11 @@
import esphome.codegen as cg
import esphome.config_validation as cv
import esphome.final_validate as fv
from esphome.components import logger
from esphome.const import (
CONF_BLOCK,
CONF_DEVICE,
CONF_FRAGMENTATION,
CONF_FREE,
CONF_ID,
CONF_LEVEL,
CONF_LOGGER,
CONF_LOOP_TIME,
)
@@ -21,38 +17,29 @@ debug_ns = cg.esphome_ns.namespace("debug")
DebugComponent = debug_ns.class_("DebugComponent", cg.PollingComponent)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(DebugComponent),
cv.Optional(CONF_DEVICE): cv.invalid(
"The 'device' option has been moved to the 'debug' text_sensor component"
),
cv.Optional(CONF_FREE): cv.invalid(
"The 'free' option has been moved to the 'debug' sensor component"
),
cv.Optional(CONF_BLOCK): cv.invalid(
"The 'block' option has been moved to the 'debug' sensor component"
),
cv.Optional(CONF_FRAGMENTATION): cv.invalid(
"The 'fragmentation' option has been moved to the 'debug' sensor component"
),
cv.Optional(CONF_LOOP_TIME): cv.invalid(
"The 'loop_time' option has been moved to the 'debug' sensor component"
),
}
).extend(cv.polling_component_schema("60s"))
def _final_validate(_):
logger_conf = fv.full_config.get()[CONF_LOGGER]
severity = logger.LOG_LEVEL_SEVERITY.index(logger_conf[CONF_LEVEL])
if severity < logger.LOG_LEVEL_SEVERITY.index("DEBUG"):
raise cv.Invalid(
"The debug component requires the logger to be at least at DEBUG level"
)
FINAL_VALIDATE_SCHEMA = _final_validate
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(DebugComponent),
cv.Optional(CONF_DEVICE): cv.invalid(
"The 'device' option has been moved to the 'debug' text_sensor component"
),
cv.Optional(CONF_FREE): cv.invalid(
"The 'free' option has been moved to the 'debug' sensor component"
),
cv.Optional(CONF_BLOCK): cv.invalid(
"The 'block' option has been moved to the 'debug' sensor component"
),
cv.Optional(CONF_FRAGMENTATION): cv.invalid(
"The 'fragmentation' option has been moved to the 'debug' sensor component"
),
cv.Optional(CONF_LOOP_TIME): cv.invalid(
"The 'loop_time' option has been moved to the 'debug' sensor component"
),
}
).extend(cv.polling_component_schema("60s")),
cv.only_on(["esp32", "esp8266"]),
)
async def to_code(config):

View File

@@ -37,6 +37,10 @@ static uint32_t get_free_heap() {
}
void DebugComponent::dump_config() {
#ifndef ESPHOME_LOG_HAS_DEBUG
return; // Can't log below if debug logging is disabled
#endif
std::string device_info;
std::string reset_reason;
device_info.reserve(256);

View File

@@ -72,6 +72,7 @@ class DemoCover : public cover::Cover, public Component {
traits.set_supports_tilt(true);
break;
case DemoCoverType::TYPE_4:
traits.set_supports_stop(true);
traits.set_is_assumed_state(true);
traits.set_supports_tilt(true);
break;

View File

@@ -40,6 +40,7 @@ DEVICE = {
NextAction = dfplayer_ns.class_("NextAction", automation.Action)
PreviousAction = dfplayer_ns.class_("PreviousAction", automation.Action)
PlayMp3Action = dfplayer_ns.class_("PlayMp3Action", automation.Action)
PlayFileAction = dfplayer_ns.class_("PlayFileAction", automation.Action)
PlayFolderAction = dfplayer_ns.class_("PlayFolderAction", automation.Action)
SetVolumeAction = dfplayer_ns.class_("SetVolumeAction", automation.Action)
@@ -113,6 +114,25 @@ async def dfplayer_previous_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
"dfplayer.play_mp3",
PlayMp3Action,
cv.maybe_simple_value(
{
cv.GenerateID(): cv.use_id(DFPlayer),
cv.Required(CONF_FILE): cv.templatable(cv.int_),
},
key=CONF_FILE,
),
)
async def dfplayer_play_mp3_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
template_ = await cg.templatable(config[CONF_FILE], args, float)
cg.add(var.set_file(template_))
return var
@automation.register_action(
"dfplayer.play",
PlayFileAction,

View File

@@ -7,10 +7,10 @@ namespace dfplayer {
static const char *const TAG = "dfplayer";
void DFPlayer::play_folder(uint16_t folder, uint16_t file) {
if (folder < 100 && file < 256) {
if (folder <= 10 && file <= 1000) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x0F, (uint8_t) folder, (uint8_t) file);
} else if (folder <= 10 && file <= 1000) {
} else if (folder < 100 && file < 256) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x14, (((uint16_t) folder) << 12) | file);
} else {

View File

@@ -35,6 +35,10 @@ class DFPlayer : public uart::UARTDevice, public Component {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x02);
}
void play_mp3(uint16_t file) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x12, file);
}
void play_file(uint16_t file) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x03, file);
@@ -113,6 +117,16 @@ class DFPlayer : public uart::UARTDevice, public Component {
DFPLAYER_SIMPLE_ACTION(NextAction, next)
DFPLAYER_SIMPLE_ACTION(PreviousAction, previous)
template<typename... Ts> class PlayMp3Action : public Action<Ts...>, public Parented<DFPlayer> {
public:
TEMPLATABLE_VALUE(uint16_t, file)
void play(Ts... x) override {
auto file = this->file_.value(x...);
this->parent_->play_mp3(file);
}
};
template<typename... Ts> class PlayFileAction : public Action<Ts...>, public Parented<DFPlayer> {
public:
TEMPLATABLE_VALUE(uint16_t, file)

View File

@@ -282,10 +282,14 @@ void DisplayBuffer::print(int x, int y, Font *font, Color color, TextAlign align
int scan_x1, scan_y1, scan_width, scan_height;
glyph.scan_area(&scan_x1, &scan_y1, &scan_width, &scan_height);
for (int glyph_x = scan_x1; glyph_x < scan_x1 + scan_width; glyph_x++) {
for (int glyph_y = scan_y1; glyph_y < scan_y1 + scan_height; glyph_y++) {
if (glyph.get_pixel(glyph_x, glyph_y)) {
this->draw_pixel_at(glyph_x + x_at, glyph_y + y_start, color);
{
const int glyph_x_max = scan_x1 + scan_width;
const int glyph_y_max = scan_y1 + scan_height;
for (int glyph_x = scan_x1; glyph_x < glyph_x_max; glyph_x++) {
for (int glyph_y = scan_y1; glyph_y < glyph_y_max; glyph_y++) {
if (glyph.get_pixel(glyph_x, glyph_y)) {
this->draw_pixel_at(glyph_x + x_at, glyph_y + y_start, color);
}
}
}
}

View File

@@ -11,6 +11,7 @@ using namespace esphome::cover;
CoverTraits EndstopCover::get_traits() {
auto traits = CoverTraits();
traits.set_supports_stop(true);
traits.set_supports_position(true);
traits.set_supports_toggle(true);
traits.set_is_assumed_state(false);

View File

@@ -163,7 +163,7 @@ RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(2, 0, 5)
# The platformio/espressif32 version to use for arduino frameworks
# - https://github.com/platformio/platform-espressif32/releases
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
ARDUINO_PLATFORM_VERSION = cv.Version(5, 2, 0)
ARDUINO_PLATFORM_VERSION = cv.Version(5, 3, 0)
# The default/recommended esp-idf framework version
# - https://github.com/espressif/esp-idf/releases
@@ -252,7 +252,7 @@ def _parse_platform_version(value):
try:
# if platform version is a valid version constraint, prefix the default package
cv.platformio_version_constraint(value)
return f"platformio/espressif32 @ {value}"
return f"platformio/espressif32@{value}"
except cv.Invalid:
return value
@@ -367,12 +367,12 @@ async def to_code(config):
cg.add_build_flag("-Wno-nonnull-compare")
cg.add_platformio_option(
"platform_packages",
[f"platformio/framework-espidf @ {conf[CONF_SOURCE]}"],
[f"platformio/framework-espidf@{conf[CONF_SOURCE]}"],
)
# platformio/toolchain-esp32ulp does not support linux_aarch64 yet and has not been updated for over 2 years
# This is espressif's own published version which is more up to date.
cg.add_platformio_option(
"platform_packages", ["espressif/toolchain-esp32ulp @ 2.35.0-20220830"]
"platform_packages", ["espressif/toolchain-esp32ulp@2.35.0-20220830"]
)
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False)
add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True)
@@ -433,7 +433,7 @@ async def to_code(config):
cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ARDUINO")
cg.add_platformio_option(
"platform_packages",
[f"platformio/framework-arduinoespressif32 @ {conf[CONF_SOURCE]}"],
[f"platformio/framework-arduinoespressif32@{conf[CONF_SOURCE]}"],
)
cg.add_platformio_option("board_build.partitions", "partitions.csv")

View File

@@ -7,6 +7,7 @@
#include <freertos/task.h>
#include <esp_idf_version.h>
#include <esp_task_wdt.h>
#include <esp_timer.h>
#include <soc/rtc.h>
#if ESP_IDF_VERSION_MAJOR >= 4

View File

@@ -2,6 +2,7 @@
#include "gpio.h"
#include "esphome/core/log.h"
#include <cinttypes>
namespace esphome {
namespace esp32 {
@@ -74,7 +75,7 @@ void ESP32InternalGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpi
std::string ESP32InternalGPIOPin::dump_summary() const {
char buffer[32];
snprintf(buffer, sizeof(buffer), "GPIO%u", static_cast<uint32_t>(pin_));
snprintf(buffer, sizeof(buffer), "GPIO%" PRIu32, static_cast<uint32_t>(pin_));
return buffer;
}

View File

@@ -5,6 +5,7 @@
#include "esphome/core/log.h"
#include <nvs_flash.h>
#include <cstring>
#include <cinttypes>
#include <vector>
#include <string>
@@ -101,7 +102,7 @@ class ESP32Preferences : public ESPPreferences {
pref->nvs_handle = nvs_handle;
uint32_t keyval = type;
pref->key = str_sprintf("%u", keyval);
pref->key = str_sprintf("%" PRIu32, keyval);
return ESPPreferenceObject(pref);
}

View File

@@ -9,8 +9,9 @@ CODEOWNERS = ["@jesserockz"]
CONFLICTS_WITH = ["esp32_ble_beacon"]
CONF_BLE_ID = "ble_id"
CONF_IO_CAPABILITY = "io_capability"
NO_BLUTOOTH_VARIANTS = [const.VARIANT_ESP32S2]
NO_BLUETOOTH_VARIANTS = [const.VARIANT_ESP32S2]
esp32_ble_ns = cg.esphome_ns.namespace("esp32_ble")
ESP32BLE = esp32_ble_ns.class_("ESP32BLE", cg.Component)
@@ -19,17 +20,28 @@ GAPEventHandler = esp32_ble_ns.class_("GAPEventHandler")
GATTcEventHandler = esp32_ble_ns.class_("GATTcEventHandler")
GATTsEventHandler = esp32_ble_ns.class_("GATTsEventHandler")
IoCapability = esp32_ble_ns.enum("IoCapability")
IO_CAPABILITY = {
"none": IoCapability.IO_CAP_NONE,
"keyboard_only": IoCapability.IO_CAP_IN,
"keyboard_display": IoCapability.IO_CAP_KBDISP,
"display_only": IoCapability.IO_CAP_OUT,
"display_yes_no": IoCapability.IO_CAP_IO,
}
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(ESP32BLE),
cv.Optional(CONF_IO_CAPABILITY, default="none"): cv.enum(
IO_CAPABILITY, lower=True
),
}
).extend(cv.COMPONENT_SCHEMA)
def validate_variant(_):
variant = get_esp32_variant()
if variant in NO_BLUTOOTH_VARIANTS:
if variant in NO_BLUETOOTH_VARIANTS:
raise cv.Invalid(f"{variant} does not support Bluetooth")
@@ -39,6 +51,7 @@ FINAL_VALIDATE_SCHEMA = validate_variant
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
cg.add(var.set_io_capability(config[CONF_IO_CAPABILITY]))
if CORE.using_esp_idf:
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)

View File

@@ -6,6 +6,7 @@
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <esp_bt_device.h>
#include <esp_gap_ble_api.h>
#include <freertos/FreeRTOS.h>
#include <freertos/FreeRTOSConfig.h>
@@ -133,8 +134,7 @@ bool ESP32BLE::ble_setup_() {
return false;
}
esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;
err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &(this->io_cap_), sizeof(uint8_t));
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gap_set_security_param failed: %d", err);
return false;
@@ -211,7 +211,38 @@ void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if
float ESP32BLE::get_setup_priority() const { return setup_priority::BLUETOOTH; }
void ESP32BLE::dump_config() { ESP_LOGCONFIG(TAG, "ESP32 BLE:"); }
void ESP32BLE::dump_config() {
const uint8_t *mac_address = esp_bt_dev_get_address();
if (mac_address) {
const char *io_capability_s;
switch (this->io_cap_) {
case ESP_IO_CAP_OUT:
io_capability_s = "display_only";
break;
case ESP_IO_CAP_IO:
io_capability_s = "display_yes_no";
break;
case ESP_IO_CAP_IN:
io_capability_s = "keyboard_only";
break;
case ESP_IO_CAP_NONE:
io_capability_s = "none";
break;
case ESP_IO_CAP_KBDISP:
io_capability_s = "keyboard_display";
break;
default:
io_capability_s = "invalid";
break;
}
ESP_LOGCONFIG(TAG, "ESP32 BLE:");
ESP_LOGCONFIG(TAG, " MAC address: %02X:%02X:%02X:%02X:%02X:%02X", mac_address[0], mac_address[1], mac_address[2],
mac_address[3], mac_address[4], mac_address[5]);
ESP_LOGCONFIG(TAG, " IO Capability: %s", io_capability_s);
} else {
ESP_LOGCONFIG(TAG, "ESP32 BLE: bluetooth stack is not enabled");
}
}
ESP32BLE *global_ble = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)

View File

@@ -25,6 +25,14 @@ typedef struct {
uint16_t mtu;
} conn_status_t;
enum IoCapability {
IO_CAP_OUT = ESP_IO_CAP_OUT,
IO_CAP_IO = ESP_IO_CAP_IO,
IO_CAP_IN = ESP_IO_CAP_IN,
IO_CAP_NONE = ESP_IO_CAP_NONE,
IO_CAP_KBDISP = ESP_IO_CAP_KBDISP,
};
class GAPEventHandler {
public:
virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) = 0;
@@ -44,6 +52,8 @@ class GATTsEventHandler {
class ESP32BLE : public Component {
public:
void set_io_capability(IoCapability io_capability) { this->io_cap_ = (esp_ble_io_cap_t) io_capability; }
void setup() override;
void loop() override;
void dump_config() override;
@@ -72,6 +82,7 @@ class ESP32BLE : public Component {
Queue<BLEEvent> ble_events_;
BLEAdvertising *advertising_;
esp_ble_io_cap_t io_cap_{ESP_IO_CAP_NONE};
};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)

View File

@@ -202,7 +202,7 @@ void ESP32Camera::loop() {
float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }
/* ---------------- constructors ---------------- */
ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
ESP32Camera::ESP32Camera() {
this->config_.pin_pwdn = -1;
this->config_.pin_reset = -1;
this->config_.pin_xclk = -1;
@@ -215,7 +215,6 @@ ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
global_esp32_camera = this;
}
ESP32Camera::ESP32Camera() : ESP32Camera("") {}
/* ---------------- setters ---------------- */
/* set pin assignment */

View File

@@ -103,7 +103,6 @@ class CameraImageReader {
/* ---------------- ESP32Camera class ---------------- */
class ESP32Camera : public Component, public EntityBase {
public:
ESP32Camera(const std::string &name);
ESP32Camera();
/* setters */

View File

@@ -0,0 +1,207 @@
#include "led_strip.h"
#ifdef USE_ESP32
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include <esp_attr.h>
namespace esphome {
namespace esp32_rmt_led_strip {
static const char *const TAG = "esp32_rmt_led_strip";
static const uint8_t RMT_CLK_DIV = 2;
void ESP32RMTLEDStripLightOutput::setup() {
ESP_LOGCONFIG(TAG, "Setting up ESP32 LED Strip...");
size_t buffer_size = this->get_buffer_size_();
ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
this->buf_ = allocator.allocate(buffer_size);
if (this->buf_ == nullptr) {
ESP_LOGE(TAG, "Cannot allocate LED buffer!");
this->mark_failed();
return;
}
this->effect_data_ = allocator.allocate(this->num_leds_);
if (this->effect_data_ == nullptr) {
ESP_LOGE(TAG, "Cannot allocate effect data!");
this->mark_failed();
return;
}
ExternalRAMAllocator<rmt_item32_t> rmt_allocator(ExternalRAMAllocator<rmt_item32_t>::ALLOW_FAILURE);
this->rmt_buf_ = rmt_allocator.allocate(buffer_size * 8); // 8 bits per byte, 1 rmt_item32_t per bit
rmt_config_t config;
memset(&config, 0, sizeof(config));
config.channel = this->channel_;
config.rmt_mode = RMT_MODE_TX;
config.gpio_num = gpio_num_t(this->pin_);
config.mem_block_num = 1;
config.clk_div = RMT_CLK_DIV;
config.tx_config.loop_en = false;
config.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
config.tx_config.carrier_en = false;
config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
config.tx_config.idle_output_en = true;
if (rmt_config(&config) != ESP_OK) {
ESP_LOGE(TAG, "Cannot initialize RMT!");
this->mark_failed();
return;
}
if (rmt_driver_install(config.channel, 0, 0) != ESP_OK) {
ESP_LOGE(TAG, "Cannot install RMT driver!");
this->mark_failed();
return;
}
}
void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high,
uint32_t bit1_low) {
float ratio = (float) APB_CLK_FREQ / RMT_CLK_DIV / 1e09f;
// 0-bit
this->bit0_.duration0 = (uint32_t) (ratio * bit0_high);
this->bit0_.level0 = 1;
this->bit0_.duration1 = (uint32_t) (ratio * bit0_low);
this->bit0_.level1 = 0;
// 1-bit
this->bit1_.duration0 = (uint32_t) (ratio * bit1_high);
this->bit1_.level0 = 1;
this->bit1_.duration1 = (uint32_t) (ratio * bit1_low);
this->bit1_.level1 = 0;
}
void ESP32RMTLEDStripLightOutput::write_state(light::LightState *state) {
// protect from refreshing too often
uint32_t now = micros();
if (*this->max_refresh_rate_ != 0 && (now - this->last_refresh_) < *this->max_refresh_rate_) {
// try again next loop iteration, so that this change won't get lost
this->schedule_show();
return;
}
this->last_refresh_ = now;
this->mark_shown_();
ESP_LOGVV(TAG, "Writing RGB values to bus...");
if (rmt_wait_tx_done(this->channel_, pdMS_TO_TICKS(1000)) != ESP_OK) {
ESP_LOGE(TAG, "RMT TX timeout");
this->status_set_warning();
return;
}
delayMicroseconds(50);
size_t buffer_size = this->get_buffer_size_();
size_t size = 0;
size_t len = 0;
uint8_t *psrc = this->buf_;
rmt_item32_t *pdest = this->rmt_buf_;
while (size < buffer_size) {
uint8_t b = *psrc;
for (int i = 0; i < 8; i++) {
pdest->val = b & (1 << (7 - i)) ? this->bit1_.val : this->bit0_.val;
pdest++;
len++;
}
size++;
psrc++;
}
if (rmt_write_items(this->channel_, this->rmt_buf_, len, false) != ESP_OK) {
ESP_LOGE(TAG, "RMT TX error");
this->status_set_warning();
return;
}
this->status_clear_warning();
}
light::ESPColorView ESP32RMTLEDStripLightOutput::get_view_internal(int32_t index) const {
int32_t r = 0, g = 0, b = 0;
switch (this->rgb_order_) {
case ORDER_RGB:
r = 0;
g = 1;
b = 2;
break;
case ORDER_RBG:
r = 0;
g = 2;
b = 1;
break;
case ORDER_GRB:
r = 1;
g = 0;
b = 2;
break;
case ORDER_GBR:
r = 2;
g = 0;
b = 1;
break;
case ORDER_BGR:
r = 2;
g = 1;
b = 0;
break;
case ORDER_BRG:
r = 1;
g = 2;
b = 0;
break;
}
uint8_t multiplier = this->is_rgbw_ ? 4 : 3;
return {this->buf_ + (index * multiplier) + r,
this->buf_ + (index * multiplier) + g,
this->buf_ + (index * multiplier) + b,
this->is_rgbw_ ? this->buf_ + (index * multiplier) + 3 : nullptr,
&this->effect_data_[index],
&this->correction_};
}
void ESP32RMTLEDStripLightOutput::dump_config() {
ESP_LOGCONFIG(TAG, "ESP32 RMT LED Strip:");
ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_);
ESP_LOGCONFIG(TAG, " Channel: %u", this->channel_);
const char *rgb_order;
switch (this->rgb_order_) {
case ORDER_RGB:
rgb_order = "RGB";
break;
case ORDER_RBG:
rgb_order = "RBG";
break;
case ORDER_GRB:
rgb_order = "GRB";
break;
case ORDER_GBR:
rgb_order = "GBR";
break;
case ORDER_BGR:
rgb_order = "BGR";
break;
case ORDER_BRG:
rgb_order = "BRG";
break;
default:
rgb_order = "UNKNOWN";
break;
}
ESP_LOGCONFIG(TAG, " RGB Order: %s", rgb_order);
ESP_LOGCONFIG(TAG, " Max refresh rate: %u", *this->max_refresh_rate_);
ESP_LOGCONFIG(TAG, " Number of LEDs: %u", this->num_leds_);
}
float ESP32RMTLEDStripLightOutput::get_setup_priority() const { return setup_priority::HARDWARE; }
} // namespace esp32_rmt_led_strip
} // namespace esphome
#endif // USE_ESP32

View File

@@ -0,0 +1,87 @@
#pragma once
#ifdef USE_ESP32
#include "esphome/components/light/addressable_light.h"
#include "esphome/components/light/light_output.h"
#include "esphome/core/color.h"
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include <driver/gpio.h>
#include <driver/rmt.h>
#include <esp_err.h>
namespace esphome {
namespace esp32_rmt_led_strip {
enum RGBOrder : uint8_t {
ORDER_RGB,
ORDER_RBG,
ORDER_GRB,
ORDER_GBR,
ORDER_BGR,
ORDER_BRG,
};
class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
public:
void setup() override;
void write_state(light::LightState *state) override;
float get_setup_priority() const override;
int32_t size() const override { return this->num_leds_; }
light::LightTraits get_traits() override {
auto traits = light::LightTraits();
if (this->is_rgbw_) {
traits.set_supported_color_modes({light::ColorMode::RGB_WHITE, light::ColorMode::WHITE});
} else {
traits.set_supported_color_modes({light::ColorMode::RGB});
}
return traits;
}
void set_pin(uint8_t pin) { this->pin_ = pin; }
void set_num_leds(uint16_t num_leds) { this->num_leds_ = num_leds; }
void set_is_rgbw(bool is_rgbw) { this->is_rgbw_ = is_rgbw; }
/// Set a maximum refresh rate in µs as some lights do not like being updated too often.
void set_max_refresh_rate(uint32_t interval_us) { this->max_refresh_rate_ = interval_us; }
void set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high, uint32_t bit1_low);
void set_rgb_order(RGBOrder rgb_order) { this->rgb_order_ = rgb_order; }
void set_rmt_channel(rmt_channel_t channel) { this->channel_ = channel; }
void clear_effect_data() override {
for (int i = 0; i < this->size(); i++)
this->effect_data_[i] = 0;
}
void dump_config() override;
protected:
light::ESPColorView get_view_internal(int32_t index) const override;
size_t get_buffer_size_() const { return this->num_leds_ * (3 + this->is_rgbw_); }
uint8_t *buf_{nullptr};
uint8_t *effect_data_{nullptr};
rmt_item32_t *rmt_buf_{nullptr};
uint8_t pin_;
uint16_t num_leds_;
bool is_rgbw_;
rmt_item32_t bit0_, bit1_;
RGBOrder rgb_order_;
rmt_channel_t channel_;
uint32_t last_refresh_{0};
optional<uint32_t> max_refresh_rate_{};
};
} // namespace esp32_rmt_led_strip
} // namespace esphome
#endif // USE_ESP32

View File

@@ -0,0 +1,151 @@
from dataclasses import dataclass
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import esp32, light
from esphome.const import (
CONF_CHIPSET,
CONF_MAX_REFRESH_RATE,
CONF_NUM_LEDS,
CONF_OUTPUT_ID,
CONF_PIN,
CONF_RGB_ORDER,
)
CODEOWNERS = ["@jesserockz"]
DEPENDENCIES = ["esp32"]
esp32_rmt_led_strip_ns = cg.esphome_ns.namespace("esp32_rmt_led_strip")
ESP32RMTLEDStripLightOutput = esp32_rmt_led_strip_ns.class_(
"ESP32RMTLEDStripLightOutput", light.AddressableLight
)
rmt_channel_t = cg.global_ns.enum("rmt_channel_t")
RGBOrder = esp32_rmt_led_strip_ns.enum("RGBOrder")
RGB_ORDERS = {
"RGB": RGBOrder.ORDER_RGB,
"RBG": RGBOrder.ORDER_RBG,
"GRB": RGBOrder.ORDER_GRB,
"GBR": RGBOrder.ORDER_GBR,
"BGR": RGBOrder.ORDER_BGR,
"BRG": RGBOrder.ORDER_BRG,
}
@dataclass
class LEDStripTimings:
bit0_high: int
bit0_low: int
bit1_high: int
bit1_low: int
CHIPSETS = {
"WS2812": LEDStripTimings(400, 1000, 1000, 400),
"SK6812": LEDStripTimings(300, 900, 600, 600),
"APA106": LEDStripTimings(350, 1360, 1360, 350),
"SM16703": LEDStripTimings(300, 900, 1360, 350),
}
CONF_IS_RGBW = "is_rgbw"
CONF_BIT0_HIGH = "bit0_high"
CONF_BIT0_LOW = "bit0_low"
CONF_BIT1_HIGH = "bit1_high"
CONF_BIT1_LOW = "bit1_low"
CONF_RMT_CHANNEL = "rmt_channel"
RMT_CHANNELS = {
esp32.const.VARIANT_ESP32: [0, 1, 2, 3, 4, 5, 6, 7],
esp32.const.VARIANT_ESP32S2: [0, 1, 2, 3],
esp32.const.VARIANT_ESP32S3: [0, 1, 2, 3],
esp32.const.VARIANT_ESP32C3: [0, 1],
}
def _validate_rmt_channel(value):
variant = esp32.get_esp32_variant()
if variant not in RMT_CHANNELS:
raise cv.Invalid(f"ESP32 variant {variant} does not support RMT.")
if value not in RMT_CHANNELS[variant]:
raise cv.Invalid(
f"RMT channel {value} is not supported for ESP32 variant {variant}."
)
return value
CONFIG_SCHEMA = cv.All(
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
{
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(ESP32RMTLEDStripLightOutput),
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_number,
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
cv.Required(CONF_RGB_ORDER): cv.enum(RGB_ORDERS, upper=True),
cv.Required(CONF_RMT_CHANNEL): _validate_rmt_channel,
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
cv.Optional(CONF_IS_RGBW, default=False): cv.boolean,
cv.Inclusive(
CONF_BIT0_HIGH,
"custom",
): cv.positive_time_period_microseconds,
cv.Inclusive(
CONF_BIT0_LOW,
"custom",
): cv.positive_time_period_microseconds,
cv.Inclusive(
CONF_BIT1_HIGH,
"custom",
): cv.positive_time_period_microseconds,
cv.Inclusive(
CONF_BIT1_LOW,
"custom",
): cv.positive_time_period_microseconds,
}
),
cv.has_exactly_one_key(CONF_CHIPSET, CONF_BIT0_HIGH),
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
await light.register_light(var, config)
await cg.register_component(var, config)
cg.add(var.set_num_leds(config[CONF_NUM_LEDS]))
cg.add(var.set_pin(config[CONF_PIN]))
if CONF_MAX_REFRESH_RATE in config:
cg.add(var.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
if CONF_CHIPSET in config:
chipset = CHIPSETS[config[CONF_CHIPSET]]
cg.add(
var.set_led_params(
chipset.bit0_high,
chipset.bit0_low,
chipset.bit1_high,
chipset.bit1_low,
)
)
else:
cg.add(
var.set_led_params(
config[CONF_BIT0_HIGH],
config[CONF_BIT0_LOW],
config[CONF_BIT1_HIGH],
config[CONF_BIT1_LOW],
)
)
cg.add(var.set_rgb_order(config[CONF_RGB_ORDER]))
cg.add(var.set_is_rgbw(config[CONF_IS_RGBW]))
cg.add(
var.set_rmt_channel(
getattr(rmt_channel_t, f"RMT_CHANNEL_{config[CONF_RMT_CHANNEL]}")
)
)

View File

@@ -125,7 +125,7 @@ def _parse_platform_version(value):
try:
# if platform version is a valid version constraint, prefix the default package
cv.platformio_version_constraint(value)
return f"platformio/espressif8266 @ {value}"
return f"platformio/espressif8266@{value}"
except cv.Invalid:
return value
@@ -181,7 +181,7 @@ async def to_code(config):
cg.add_platformio_option("platform", conf[CONF_PLATFORM_VERSION])
cg.add_platformio_option(
"platform_packages",
[f"platformio/framework-arduinoespressif8266 @ {conf[CONF_SOURCE]}"],
[f"platformio/framework-arduinoespressif8266@{conf[CONF_SOURCE]}"],
)
# Default for platformio is LWIP2_LOW_MEMORY with:

View File

@@ -34,6 +34,7 @@ ETHERNET_TYPES = {
"DP83848": EthernetType.ETHERNET_TYPE_DP83848,
"IP101": EthernetType.ETHERNET_TYPE_IP101,
"JL1101": EthernetType.ETHERNET_TYPE_JL1101,
"KSZ8081": EthernetType.ETHERNET_TYPE_KSZ8081,
}
emac_rmii_clock_mode_t = cg.global_ns.enum("emac_rmii_clock_mode_t")

View File

@@ -26,8 +26,10 @@ EthernetComponent::EthernetComponent() { global_eth_component = this; }
void EthernetComponent::setup() {
ESP_LOGCONFIG(TAG, "Setting up Ethernet...");
// Delay here to allow power to stabilise before Ethernet is initialised.
delay(300); // NOLINT
if (esp_reset_reason() != ESP_RST_DEEPSLEEP) {
// Delay here to allow power to stabilise before Ethernet is initialized.
delay(300); // NOLINT
}
esp_err_t err;
err = esp_netif_init();
@@ -52,26 +54,29 @@ void EthernetComponent::setup() {
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
esp_eth_phy_t *phy;
switch (this->type_) {
case ETHERNET_TYPE_LAN8720: {
phy = esp_eth_phy_new_lan87xx(&phy_config);
this->phy_ = esp_eth_phy_new_lan87xx(&phy_config);
break;
}
case ETHERNET_TYPE_RTL8201: {
phy = esp_eth_phy_new_rtl8201(&phy_config);
this->phy_ = esp_eth_phy_new_rtl8201(&phy_config);
break;
}
case ETHERNET_TYPE_DP83848: {
phy = esp_eth_phy_new_dp83848(&phy_config);
this->phy_ = esp_eth_phy_new_dp83848(&phy_config);
break;
}
case ETHERNET_TYPE_IP101: {
phy = esp_eth_phy_new_ip101(&phy_config);
this->phy_ = esp_eth_phy_new_ip101(&phy_config);
break;
}
case ETHERNET_TYPE_JL1101: {
phy = esp_eth_phy_new_jl1101(&phy_config);
this->phy_ = esp_eth_phy_new_jl1101(&phy_config);
break;
}
case ETHERNET_TYPE_KSZ8081: {
this->phy_ = esp_eth_phy_new_ksz8081(&phy_config);
break;
}
default: {
@@ -80,7 +85,7 @@ void EthernetComponent::setup() {
}
}
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, this->phy_);
this->eth_handle_ = nullptr;
err = esp_eth_driver_install(&eth_config, &this->eth_handle_);
ESPHL_ERROR_CHECK(err, "ETH driver install error");
@@ -140,7 +145,7 @@ void EthernetComponent::loop() {
}
void EthernetComponent::dump_config() {
std::string eth_type;
const char *eth_type;
switch (this->type_) {
case ETHERNET_TYPE_LAN8720:
eth_type = "LAN8720";
@@ -158,6 +163,14 @@ void EthernetComponent::dump_config() {
eth_type = "IP101";
break;
case ETHERNET_TYPE_JL1101:
eth_type = "JL1101";
break;
case ETHERNET_TYPE_KSZ8081:
eth_type = "KSZ8081";
break;
default:
eth_type = "Unknown";
break;
@@ -170,7 +183,8 @@ void EthernetComponent::dump_config() {
}
ESP_LOGCONFIG(TAG, " MDC Pin: %u", this->mdc_pin_);
ESP_LOGCONFIG(TAG, " MDIO Pin: %u", this->mdio_pin_);
ESP_LOGCONFIG(TAG, " Type: %s", eth_type.c_str());
ESP_LOGCONFIG(TAG, " Type: %s", eth_type);
ESP_LOGCONFIG(TAG, " PHY addr: %u", this->phy_addr_);
}
float EthernetComponent::get_setup_priority() const { return setup_priority::WIFI; }
@@ -263,7 +277,7 @@ void EthernetComponent::start_connect_() {
#endif
dns_setserver(0, &d);
}
if (uint32_t(this->manual_ip_->dns1) != 0) {
if (uint32_t(this->manual_ip_->dns2) != 0) {
ip_addr_t d;
#if LWIP_IPV6
d.type = IPADDR_TYPE_V4;
@@ -343,6 +357,21 @@ std::string EthernetComponent::get_use_address() const {
void EthernetComponent::set_use_address(const std::string &use_address) { this->use_address_ = use_address; }
bool EthernetComponent::powerdown() {
ESP_LOGI(TAG, "Powering down ethernet PHY");
if (this->phy_ == nullptr) {
ESP_LOGE(TAG, "Ethernet PHY not assigned");
return false;
}
this->connected_ = false;
this->started_ = false;
if (this->phy_->pwrctl(this->phy_, false) != ESP_OK) {
ESP_LOGE(TAG, "Error powering down ethernet PHY");
return false;
}
return true;
}
} // namespace ethernet
} // namespace esphome

View File

@@ -14,11 +14,13 @@ namespace esphome {
namespace ethernet {
enum EthernetType {
ETHERNET_TYPE_LAN8720 = 0,
ETHERNET_TYPE_UNKNOWN = 0,
ETHERNET_TYPE_LAN8720,
ETHERNET_TYPE_RTL8201,
ETHERNET_TYPE_DP83848,
ETHERNET_TYPE_IP101,
ETHERNET_TYPE_JL1101,
ETHERNET_TYPE_KSZ8081,
};
struct ManualIP {
@@ -43,6 +45,7 @@ class EthernetComponent : public Component {
void dump_config() override;
float get_setup_priority() const override;
bool can_proceed() override;
void on_shutdown() override { powerdown(); }
bool is_connected();
void set_phy_addr(uint8_t phy_addr);
@@ -56,6 +59,7 @@ class EthernetComponent : public Component {
network::IPAddress get_ip_address();
std::string get_use_address() const;
void set_use_address(const std::string &use_address);
bool powerdown();
protected:
static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
@@ -69,7 +73,7 @@ class EthernetComponent : public Component {
int power_pin_{-1};
uint8_t mdc_pin_{23};
uint8_t mdio_pin_{18};
EthernetType type_{ETHERNET_TYPE_LAN8720};
EthernetType type_{ETHERNET_TYPE_UNKNOWN};
emac_rmii_clock_mode_t clk_mode_{EMAC_CLK_EXT_IN};
emac_rmii_clock_gpio_t clk_gpio_{EMAC_CLK_IN_GPIO};
optional<ManualIP> manual_ip_{};
@@ -80,6 +84,7 @@ class EthernetComponent : public Component {
uint32_t connect_begin_;
esp_netif_t *eth_netif_{nullptr};
esp_eth_handle_t eth_handle_;
esp_eth_phy_t *phy_{nullptr};
};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)

View File

@@ -106,20 +106,18 @@ void EZOSensor::loop() {
break;
}
ESP_LOGV(TAG, "Received buffer \"%s\" for command type %s", buf, EZO_COMMAND_TYPE_STRINGS[to_run->command_type]);
ESP_LOGV(TAG, "Received buffer \"%s\" for command type %s", &buf[1], EZO_COMMAND_TYPE_STRINGS[to_run->command_type]);
if ((buf[0] == 1) || (to_run->command_type == EzoCommandType::EZO_CALIBRATION)) { // EZO_CALIBRATION returns 0-3
// some sensors return multiple comma-separated values, terminate string after first one
for (size_t i = 1; i < sizeof(buf) - 1; i++) {
if (buf[i] == ',') {
buf[i] = '\0';
break;
}
}
if (buf[0] == 1) {
std::string payload = reinterpret_cast<char *>(&buf[1]);
if (!payload.empty()) {
switch (to_run->command_type) {
case EzoCommandType::EZO_READ: {
// some sensors return multiple comma-separated values, terminate string after first one
int start_location = 0;
if ((start_location = payload.find(',')) != std::string::npos) {
payload.erase(start_location);
}
auto val = parse_number<float>(payload);
if (!val.has_value()) {
ESP_LOGW(TAG, "Can't convert '%s' to number!", payload.c_str());
@@ -154,7 +152,10 @@ void EZOSensor::loop() {
break;
}
case EzoCommandType::EZO_T: {
this->t_callback_.call(payload);
int start_location = 0;
if ((start_location = payload.find(',')) != std::string::npos) {
this->t_callback_.call(payload.substr(start_location + 1));
}
break;
}
case EzoCommandType::EZO_CUSTOM: {

View File

@@ -12,14 +12,14 @@ static const char *const TAG = "ezo.sensor";
enum EzoCommandType : uint8_t {
EZO_READ = 0,
EZO_LED = 1,
EZO_DEVICE_INFORMATION = 2,
EZO_SLOPE = 3,
EZO_LED,
EZO_DEVICE_INFORMATION,
EZO_SLOPE,
EZO_CALIBRATION,
EZO_SLEEP = 4,
EZO_I2C = 5,
EZO_T = 6,
EZO_CUSTOM = 7
EZO_SLEEP,
EZO_I2C,
EZO_T,
EZO_CUSTOM
};
enum EzoCalibrationType : uint8_t { EZO_CAL_LOW = 0, EZO_CAL_MID = 1, EZO_CAL_HIGH = 2 };

View File

@@ -63,7 +63,7 @@ FanIsOffCondition = fan_ns.class_("FanIsOffCondition", automation.Condition.temp
FAN_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
{
cv.GenerateID(): cv.declare_id(Fan),
cv.Optional(CONF_RESTORE_MODE, default="RESTORE_DEFAULT_OFF"): cv.enum(
cv.Optional(CONF_RESTORE_MODE, default="ALWAYS_OFF"): cv.enum(
RESTORE_MODES, upper=True, space="_"
),
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),

View File

@@ -80,9 +80,6 @@ void FanRestoreState::apply(Fan &fan) {
fan.publish_state();
}
Fan::Fan() : EntityBase("") {}
Fan::Fan(const std::string &name) : EntityBase(name) {}
FanCall Fan::turn_on() { return this->make_call().set_state(true); }
FanCall Fan::turn_off() { return this->make_call().set_state(false); }
FanCall Fan::toggle() { return this->make_call().set_state(!this->state); }

View File

@@ -99,10 +99,6 @@ struct FanRestoreState {
class Fan : public EntityBase {
public:
Fan();
/// Construct the fan with name.
explicit Fan(const std::string &name);
/// The current on/off state of the fan.
bool state{false};
/// The current oscillation state of the fan.

View File

@@ -15,7 +15,6 @@ enum ESPDEPRECATED("LegacyFanDirection members are deprecated, use FanDirection
class ESPDEPRECATED("FanState is deprecated, use Fan instead.", "2022.2") FanState : public Fan, public Component {
public:
FanState() = default;
explicit FanState(const std::string &name) : Fan(name) {}
/// Get the traits of this fan.
FanTraits get_traits() override { return this->traits_; }

View File

@@ -41,6 +41,7 @@ void FeedbackCover::setup() {
CoverTraits FeedbackCover::get_traits() {
auto traits = CoverTraits();
traits.set_supports_stop(true);
traits.set_supports_position(true);
traits.set_supports_toggle(true);
traits.set_is_assumed_state(this->assumed_state_);

View File

@@ -77,10 +77,12 @@ void FingerprintGrowComponent::finish_enrollment(uint8_t result) {
this->enrollment_done_callback_.call(this->enrollment_slot_);
this->get_fingerprint_count_();
} else {
this->enrollment_failed_callback_.call(this->enrollment_slot_);
if (this->enrollment_slot_ != ENROLLMENT_SLOT_UNUSED) {
this->enrollment_failed_callback_.call(this->enrollment_slot_);
}
}
this->enrollment_image_ = 0;
this->enrollment_slot_ = 0;
this->enrollment_slot_ = ENROLLMENT_SLOT_UNUSED;
if (this->enrolling_binary_sensor_ != nullptr) {
this->enrolling_binary_sensor_->publish_state(false);
}

View File

@@ -13,6 +13,8 @@ namespace fingerprint_grow {
static const uint16_t START_CODE = 0xEF01;
static const uint16_t ENROLLMENT_SLOT_UNUSED = 0xFFFF;
enum GrowPacketType {
COMMAND = 0x01,
DATA = 0x02,
@@ -158,7 +160,7 @@ class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevic
uint32_t new_password_ = -1;
GPIOPin *sensing_pin_{nullptr};
uint8_t enrollment_image_ = 0;
uint16_t enrollment_slot_ = 0;
uint16_t enrollment_slot_ = ENROLLMENT_SLOT_UNUSED;
uint8_t enrollment_buffers_ = 5;
bool waiting_removal_ = false;
uint32_t last_aura_led_control_ = 0;

View File

@@ -0,0 +1,40 @@
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.components import i2c
from esphome.const import CONF_ID, CONF_VOLTAGE
CODEOWNERS = ["@jesserockz"]
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
gp8403_ns = cg.esphome_ns.namespace("gp8403")
GP8403 = gp8403_ns.class_("GP8403", cg.Component, i2c.I2CDevice)
GP8403Voltage = gp8403_ns.enum("GP8403Voltage")
CONF_GP8403_ID = "gp8403_id"
VOLTAGES = {
"5V": GP8403Voltage.GP8403_VOLTAGE_5V,
"10V": GP8403Voltage.GP8403_VOLTAGE_10V,
}
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(GP8403),
cv.Required(CONF_VOLTAGE): cv.enum(VOLTAGES, upper=True),
}
)
.extend(cv.COMPONENT_SCHEMA)
.extend(i2c.i2c_device_schema(0x58))
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
cg.add(var.set_voltage(config[CONF_VOLTAGE]))

View File

@@ -0,0 +1,21 @@
#include "gp8403.h"
#include "esphome/core/log.h"
namespace esphome {
namespace gp8403 {
static const char *const TAG = "gp8403";
static const uint8_t RANGE_REGISTER = 0x01;
void GP8403::setup() { this->write_register(RANGE_REGISTER, (uint8_t *) (&this->voltage_), 1); }
void GP8403::dump_config() {
ESP_LOGCONFIG(TAG, "GP8403:");
ESP_LOGCONFIG(TAG, " Voltage: %dV", this->voltage_ == GP8403_VOLTAGE_5V ? 5 : 10);
LOG_I2C_DEVICE(this);
}
} // namespace gp8403
} // namespace esphome

View File

@@ -0,0 +1,27 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
namespace esphome {
namespace gp8403 {
enum GP8403Voltage {
GP8403_VOLTAGE_5V = 0x00,
GP8403_VOLTAGE_10V = 0x11,
};
class GP8403 : public Component, public i2c::I2CDevice {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA; }
void set_voltage(gp8403::GP8403Voltage voltage) { this->voltage_ = voltage; }
protected:
GP8403Voltage voltage_;
};
} // namespace gp8403
} // namespace esphome

View File

@@ -0,0 +1,31 @@
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.components import i2c, output
from esphome.const import CONF_ID, CONF_CHANNEL
from .. import gp8403_ns, GP8403, CONF_GP8403_ID
DEPENDENCIES = ["gp8403"]
GP8403Output = gp8403_ns.class_(
"GP8403Output", cg.Component, i2c.I2CDevice, output.FloatOutput
)
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(GP8403Output),
cv.GenerateID(CONF_GP8403_ID): cv.use_id(GP8403),
cv.Required(CONF_CHANNEL): cv.one_of(0, 1),
}
).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await output.register_output(var, config)
await cg.register_parented(var, config[CONF_GP8403_ID])
cg.add(var.set_channel(config[CONF_CHANNEL]))

View File

@@ -0,0 +1,26 @@
#include "gp8403_output.h"
#include "esphome/core/log.h"
namespace esphome {
namespace gp8403 {
static const char *const TAG = "gp8403.output";
static const uint8_t OUTPUT_REGISTER = 0x02;
void GP8403Output::dump_config() {
ESP_LOGCONFIG(TAG, "GP8403 Output:");
ESP_LOGCONFIG(TAG, " Channel: %u", this->channel_);
}
void GP8403Output::write_state(float state) {
uint16_t value = ((uint16_t) (state * 4095)) << 4;
i2c::ErrorCode err = this->parent_->write_register(OUTPUT_REGISTER + (2 * this->channel_), (uint8_t *) &value, 2);
if (err != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Error writing to GP8403, code %d", err);
}
}
} // namespace gp8403
} // namespace esphome

View File

@@ -0,0 +1,25 @@
#pragma once
#include "esphome/components/output/float_output.h"
#include "esphome/core/component.h"
#include "esphome/components/gp8403/gp8403.h"
namespace esphome {
namespace gp8403 {
class GP8403Output : public Component, public output::FloatOutput, public Parented<GP8403> {
public:
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA - 1; }
void set_channel(uint8_t channel) { this->channel_ = channel; }
void write_state(float state) override;
protected:
uint8_t channel_;
};
} // namespace gp8403
} // namespace esphome

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