Compare commits

..

213 Commits

Author SHA1 Message Date
Jesse Hills
d3fda37615 Merge pull request #3042 from esphome/bump-2022.1.0b2
2022.1.0b2
2022-01-13 22:21:45 +13:00
Jesse Hills
cbe3092404 Bump version to 2022.1.0b2 2022-01-13 21:28:45 +13:00
Paulus Schoutsen
6dfe3039d0 Bump dashboard to 20220113.2 (#3041) 2022-01-13 21:28:45 +13:00
Paulus Schoutsen
d6009453df Add factory to download name (#3040) 2022-01-13 21:28:45 +13:00
Jesse Hills
c81323ef91 Merge pull request #3039 from esphome/bump-2022.1.0b1
2022.1.0b1
2022-01-13 12:12:07 +13:00
Jesse Hills
961c27f1c2 Bump version to 2022.1.0b1 2022-01-13 11:02:07 +13:00
Jesse Hills
fe4a14e6cc Merge branch 'dev' into bump-2022.1.0b1 2022-01-13 11:02:07 +13:00
Jesse Hills
50848c2f4d Merge pull request #2966 from esphome/bump-2021.12.3
2021.12.3
2021-12-30 14:54:49 +13:00
Jesse Hills
d32633b3c7 Update curl package version in docker (#2939) 2021-12-30 14:32:29 +13:00
Jesse Hills
b37739eec2 Bump version to 2021.12.3 2021-12-30 13:58:47 +13:00
Jesse Hills
28f87dc804 Remove -e for hassio images (#2964) 2021-12-30 13:58:47 +13:00
Jesse Hills
41879e41e6 Workaround installing as editable package not working (#2936) 2021-12-30 13:58:47 +13:00
Jesse Hills
fc0a6546a2 Only allow internal pins for dht sensor (#2940) 2021-12-30 13:58:47 +13:00
Jesse Hills
ffd4280d6c Require arduino in webserver for better validation (#2941) 2021-12-30 13:58:46 +13:00
Jesse Hills
db3b955b0f Merge pull request #2932 from esphome/bump-2021.12.2
2021.12.2
2021-12-21 12:45:27 +13:00
Jesse Hills
5516f65971 Bump version to 2021.12.2 2021-12-21 08:24:08 +13:00
Oxan van Leeuwen
9471df0a1b Fix MQTT button press action (#2917) 2021-12-21 08:24:07 +13:00
Oxan van Leeuwen
6d39f64be7 Don't disable idle task WDT when it's not enabled (#2856) 2021-12-21 08:24:07 +13:00
Jesse Hills
b89d0a9a73 Merge pull request #2915 from esphome/bump-2021.12.1
2021.12.1
2021-12-15 16:36:39 +13:00
Jesse Hills
4bb779d9a5 Bump version to 2021.12.1 2021-12-15 14:57:32 +13:00
wilberforce
386a5b6362 Allow button POST on press from web server (#2913) 2021-12-15 14:57:32 +13:00
Oxan van Leeuwen
e32a999cd0 Set text sensor state property to filter output (#2893) 2021-12-15 14:57:32 +13:00
Jesse Hills
bfbc6a4bad Merge pull request #2907 from esphome/bump-2021.12.0
2021.12.0
2021-12-12 07:59:37 +13:00
Jesse Hills
8c9e0e552d Bump version to 2021.12.0 2021-12-12 07:10:51 +13:00
Jesse Hills
8aaf9fd83f Merge pull request #2905 from esphome/bump-2021.12.0b6
2021.12.0b6
2021-12-11 21:54:49 +13:00
Jesse Hills
08057720b8 Bump version to 2021.12.0b6 2021-12-11 21:07:07 +13:00
Jesse Hills
bfaa648837 Bump esphome-dashboard to 20211211.0 (#2904) 2021-12-11 21:07:07 +13:00
Keith Burzinski
d504daef91 Fix for two points setting when fan_only_cooling is disabled (#2903)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
Co-authored-by: Keith Burzinski <kburzinski@kbx-mbp2021.ad.kbx81.net>
2021-12-11 21:07:07 +13:00
Jesse Hills
b8d3ef2f49 Merge pull request #2899 from esphome/bump-2021.12.0b5
2021.12.0b5
2021-12-10 10:55:55 +13:00
Jesse Hills
3bf6320030 Bump version to 2021.12.0b5 2021-12-10 09:55:48 +13:00
Guillermo Ruffino
708b928c73 Modbus number/output use write single (#2896)
Co-authored-by: Martin <25747549+martgras@users.noreply.github.com>
2021-12-10 09:55:48 +13:00
Jesse Hills
649366ff44 Fix published state for modbus number (#2894) 2021-12-10 09:55:47 +13:00
Jesse Hills
e5c9e87fad Merge pull request #2890 from esphome/bump-2021.12.0b4
2021.12.0b4
2021-12-10 09:50:29 +13:00
Jesse Hills
f3d9d707b6 Bump version to 2021.12.0b4 2021-12-08 12:58:14 +13:00
Jesse Hills
090e10730c Bump esphome-dashboard to 20211208.0 (#2887) 2021-12-08 12:58:14 +13:00
Jesse Hills
fbc84861c7 Use new platform component config blocks for wizard (#2885) 2021-12-08 12:58:14 +13:00
Carlos Garcia Saura
e763469af8 Feed watchdog while setting up OTA (#2876) 2021-12-08 12:58:14 +13:00
Jesse Hills
3c0c514e44 Merge pull request #2880 from esphome/bump-2021.12.0b3
2021.12.0b3
2021-12-07 15:27:08 +13:00
Jesse Hills
ed5e2dd332 Bump version to 2021.12.0b3 2021-12-07 07:47:48 +13:00
Jesse Hills
09b7c6f550 Bump esphome-dashboard to 20211207.0 (#2877) 2021-12-07 07:47:48 +13:00
Oxan van Leeuwen
df315a1f51 Feed watchdog when no component loops (#2857) 2021-12-07 07:47:48 +13:00
Jesse Hills
7ee4bb621c Allow wizard to specify secrets (#2875) 2021-12-07 07:47:48 +13:00
Jesse Hills
24874f4c3c Adopt using wifi secrets that should exist at this point (#2874) 2021-12-07 07:47:48 +13:00
Jesse Hills
c128880033 Add endpoint to fetch secrets keys (#2873) 2021-12-07 07:47:48 +13:00
Massimiliano Ravelli
a66e94a0b0 Ignore already stopped dhcp for ethernet (#2862)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2021-12-07 07:47:48 +13:00
Oxan van Leeuwen
56870ed4a8 Fix MCP23x17 not disabling pullup after config change (#2855) 2021-12-07 07:47:48 +13:00
Martin
3ac720df47 SPS30 : fix i2c read size (#2866) 2021-12-07 07:47:48 +13:00
Carlos Garcia Saura
1bc757ad06 ADC: Turn verbose the debugging "got voltage" (#2863) 2021-12-07 07:47:48 +13:00
Martin
f72abc6f3d tlc59208f : fix compilation error (#2867) 2021-12-07 07:47:48 +13:00
Jesse Hills
5ac88de985 Bump esphome-dashboard to 20211206.0 (#2870) 2021-12-07 07:47:48 +13:00
Jesse Hills
0826b367d6 Merge pull request #2853 from esphome/bump-2021.12.0b2
2021.12.0b2
2021-12-03 08:07:30 +13:00
Jesse Hills
329bf861d6 Bump version to 2021.12.0b2 2021-12-03 07:54:34 +13:00
Oxan van Leeuwen
9dcd3d18a0 Update ota_component.cpp (#2852) 2021-12-03 07:54:34 +13:00
Jesse Hills
db66cd88b6 Merge pull request #2851 from esphome/bump-2021.12.0b1
2021.12.0b1
2021-12-02 21:32:43 +13:00
Jesse Hills
86c205fe43 Remove blank line 2021-12-02 21:08:11 +13:00
Jesse Hills
c6414138c7 Bump version to 2021.12.0b1 2021-12-02 19:38:49 +13:00
Jesse Hills
36b355eb82 Merge branch 'dev' into bump-2021.12.0b1 2021-12-02 19:38:44 +13:00
Jesse Hills
7be9291b13 Merge pull request #2821 from esphome/bump-2021.11.4
2021.11.4
2021-11-29 13:23:47 +13:00
Jesse Hills
ea9e75039b Bump version to 2021.11.4 2021-11-29 10:18:49 +13:00
Conclusio
a5fb036011 Add delay to improve stability (#2793) 2021-11-29 10:18:48 +13:00
Dave T
e55506f9db Correct bitmask for third color (blue) scaling. (#2817) 2021-11-29 10:18:48 +13:00
Carlos Garcia Saura
50ec1d0445 Fix compilation error for WPA enterprise in ESP-IDF (#2815) 2021-11-29 10:18:48 +13:00
Oxan van Leeuwen
3d5e1d8d91 Fix parsing of multiple values in EZO sensor (#2814)
Co-authored-by: Lydia Sevelt <LydiaSevelt@gmail.com>
2021-11-29 10:18:48 +13:00
Oxan van Leeuwen
db2128a344 Fix parsing numbers in Anova (#2816) 2021-11-29 10:18:48 +13:00
Jesse Hills
21db43db06 Merge pull request #2808 from esphome/bump-2021.11.3
2021.11.3
2021-11-28 00:01:16 +13:00
Jesse Hills
5009b3029f Bump version to 2021.11.3 2021-11-27 21:13:01 +13:00
Maurice Makaay
57a029189c Add missing nvs_flash_init() to ESP32 preferences code (#2805)
Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
2021-11-27 21:13:01 +13:00
Jesse Hills
0cb715bb76 Merge pull request #2799 from esphome/bump-2021.11.2
2021.11.2
2021-11-26 09:25:37 +13:00
Jesse Hills
7d03823afd Bump version to 2021.11.2 2021-11-26 09:02:54 +13:00
Oxan van Leeuwen
8e1c9f5042 Fix parsing numbers from null-terminated buffers (#2755) 2021-11-26 09:02:54 +13:00
Samuel Sieb
980b7cda8f Remove floating point ops from the ISR (#2751)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2021-11-26 09:02:53 +13:00
Kamil Trzciński
3a72dd5cb6 esp32_camera_web_server: Improve support for MotionEye (#2777) 2021-11-26 09:02:53 +13:00
Dave T
3178243811 Fix frame scaling for animated gifs (#2750) 2021-11-26 09:02:53 +13:00
Maurice Makaay
d30e2f2a4f Allow UART debug configuration with no after: definition (#2753) 2021-11-26 09:02:53 +13:00
Jesse Hills
6226dae05c Merge pull request #2744 from esphome/bump-2021.11.1
2021.11.1
2021-11-17 23:45:43 +13:00
Jesse Hills
9c6a475a6e Bump version to 2021.11.1 2021-11-17 23:31:38 +13:00
Franck Nijhof
8294d10d5b Re-instate device class update for binary sensors (#2743) 2021-11-17 23:31:38 +13:00
Evgeny
67558bec47 Fix HM3301 AQI index calculator (#2739) 2021-11-17 23:31:38 +13:00
Jesse Hills
84873d4074 Merge pull request #2742 from esphome/bump-2021.11.0
2021.11.0
2021-11-17 22:18:29 +13:00
Jesse Hills
58a0b28a39 Bump version to 2021.11.0 2021-11-17 21:58:30 +13:00
Jesse Hills
b37d3a66cc Merge pull request #2738 from esphome/bump-2021.11.0b9
2021.11.0b9
2021-11-17 10:27:41 +13:00
Jesse Hills
7e495a5e27 Bump version to 2021.11.0b9 2021-11-17 08:00:26 +13:00
rotarykite
c41547fd4a Fix senseair component uart read timeout (#2658)
Co-authored-by: DAVe3283 <DAVe3283+GitHub@gmail.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Chua Jun Chieh <junchieh.chua@softspace.com.my>
2021-11-17 08:00:26 +13:00
Ryan Hoffman
0d47d41c85 Use as_reversed_hex_array in ble_sensor to fix UUID parsing (#2737)
#1627 renamed as_hex_array to as_reversed_hex_array but forgot to rename these users.
2021-11-17 08:00:26 +13:00
Jesse Hills
41a3a17456 Merge pull request #2734 from esphome/bump-2021.11.0b8
2021.11.0b8
2021-11-16 13:50:10 +13:00
Jesse Hills
cbbafbcca2 Bump version to 2021.11.0b8 2021-11-16 12:53:56 +13:00
Jesse Hills
c75566b374 Fix zeroconf time comparisons (#2733)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-11-16 12:53:56 +13:00
Jesse Hills
7279f1fcc1 Merge pull request #2732 from esphome/bump-2021.11.0b7
2021.11.0b7
2021-11-16 12:19:07 +13:00
Jesse Hills
d7432f7c10 Bump version to 2021.11.0b7 2021-11-16 11:05:51 +13:00
Jesse Hills
b0a0a153f3 Improv serial/checksum changes (#2731)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-11-16 11:05:51 +13:00
Jesse Hills
024632dbd0 Merge pull request #2730 from esphome/bump-2021.11.0b6
2021.11.0b6
2021-11-16 10:53:11 +13:00
Jesse Hills
0a545a28b9 Bump version to 2021.11.0b6 2021-11-16 09:59:00 +13:00
Jesse Hills
0f2df59998 Add zeroconf as a direct dependency and lock the version (#2729) 2021-11-16 09:58:59 +13:00
Jesse Hills
29a7d32f77 Merge pull request #2725 from esphome/bump-2021.11.0b5
2021.11.0b5
2021-11-15 13:42:59 +13:00
Jesse Hills
687a7e9b2f Bump version to 2021.11.0b5 2021-11-15 12:02:18 +13:00
Alexandre-Jacques St-Jacques
09e8782318 Remove unnecessary duplicate touch_pad_filter_start (#2724) 2021-11-15 12:02:18 +13:00
Jesse Hills
f2aea02210 Merge pull request #2723 from esphome/bump-2021.11.0b4
2021.11.0b4
2021-11-15 11:42:59 +13:00
Jesse Hills
194f922312 Bump version to 2021.11.0b4 2021-11-15 11:03:40 +13:00
Jesse Hills
fea3c48098 Fix indentation of write_lambda for modbus_controller number (#2722) 2021-11-15 11:03:39 +13:00
Sergey V. DUDANOV
c2f57baec2 RemoteTransmitter fix. Bug from version 2021.10. Some changes. (#2706) 2021-11-15 11:03:39 +13:00
Oxan van Leeuwen
f4a140e126 Feed WDT between doing ESP32 touchpad measurements (#2720) 2021-11-15 11:03:39 +13:00
Oxan van Leeuwen
ab506b09fe Restore InterruptLock on wifi-less ESP8266 (#2712) 2021-11-15 11:03:39 +13:00
Krzysztof Białek
87e1cdeedb Allow setting custom command_topic for Select and Number components (#2714) 2021-11-15 11:03:39 +13:00
Jesse Hills
81a36146ef Bump ESPAsyncWebServer to 2.1.0 (#2686) 2021-11-15 11:03:39 +13:00
Jesse Hills
7fa4a68a27 Merge pull request #2704 from esphome/bump-2021.11.0b3
2021.11.0b3
2021-11-12 17:21:58 +13:00
Jesse Hills
f1c5e2ef81 Bump version to 2021.11.0b3 2021-11-12 16:12:31 +13:00
lcavalli
b526155cce Update device classes for binary sensors (#2703) 2021-11-12 16:12:31 +13:00
Jesse Hills
62c3f301e7 Only allow prometheus when using arduino (#2697) 2021-11-12 16:12:31 +13:00
Jesse Hills
38cb988809 Remove my.ha links from improv (#2695) 2021-11-12 16:12:31 +13:00
Jesse Hills
b976ac54c8 Merge pull request #2693 from esphome/bump-2021.11.0b2
2021.11.0b2
2021-11-11 12:52:35 +13:00
Jesse Hills
78026e766f Bump version to 2021.11.0b2 2021-11-11 12:25:41 +13:00
Oxan van Leeuwen
b4cd8d21a5 Enable addressable light power supply based on raw values (#2690) 2021-11-11 12:25:41 +13:00
Maurice Makaay
7552893311 Uart debugging support (#2478)
Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
Co-authored-by: Maurice Makaay <account-github@makaay.nl>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2021-11-11 12:25:41 +13:00
Carlos Garcia Saura
21c896d8f8 [remote_transmitter] accurate pulse timing for ESP8266 (#2476) 2021-11-11 12:25:40 +13:00
Jesse Hills
4b7fe202ec Fix template number initial value being NaN (#2692) 2021-11-11 12:25:40 +13:00
Jesse Hills
9f4519210f Merge pull request #2691 from esphome/bump-2021.11.0b1
2021.11.0b1
2021-11-11 11:05:45 +13:00
Jesse Hills
b0506afa5b Merge branch 'beta' into bump-2021.11.0b1 2021-11-11 10:48:23 +13:00
Jesse Hills
8cbb379898 Remove import (not sure how it got there) 2021-11-11 10:35:18 +13:00
Jesse Hills
b226215593 Bump version to 2021.11.0b1 2021-11-11 10:10:05 +13:00
Jesse Hills
19970729a9 Merge branch 'dev' into bump-2021.11.0b1 2021-11-11 10:10:04 +13:00
Jesse Hills
d2ebfd2833 Merge pull request #2634 from esphome/bump-2021.10.3
2021.10.3
2021-10-27 11:21:08 +13:00
Jesse Hills
bd782fc828 Bump version to 2021.10.3 2021-10-27 10:49:11 +13:00
Jesse Hills
23560e608c Fix select.set using lambda (#2633) 2021-10-27 10:49:10 +13:00
Jan Čermák
f1377b560e Fix pin number validation for sn74hc595 (#2621) 2021-10-27 10:49:10 +13:00
Martin
72108684ea fix modbus output (#2630) 2021-10-27 10:49:10 +13:00
Jesse Hills
c6adaaea97 Remove power and energy from sensors that are not true power (#2628) 2021-10-27 10:49:10 +13:00
Otto Winter
91999a38ca Fix glue code missing micros() (#2623) 2021-10-27 10:49:10 +13:00
0hax
b34eed125d Teleinfo ptec (#2599)
* teleinfo: handle historical mode correctly.

In historical mode, tags like PTEC leads to an issue where we detect a
timestamp wheras this is not possible in historical mode.

PTEC teleinfo tag looks like:
    PTEC HP..
Instead of the usual format
    IINST1 001 I

This make our data parsing fails.

While at here, make sure we continue parsing other tags even if parsing
one of the tag fails.

Signed-off-by: 0hax <0hax@protonmail.com>

* teleinfo: fix compilation with loglevel set to debug.

Signed-off-by: 0hax <0hax@protonmail.com>
2021-10-27 10:49:10 +13:00
Stefan Agner
2abe09529a Autodetect flash size (#2615) 2021-10-27 10:49:10 +13:00
Otto Winter
9aaaf4dd4b Bump platform-espressif8266 from 2.6.2 to 2.6.3 (#2620) 2021-10-27 10:49:09 +13:00
Andreas Hergert
cbfbcf7f1b fixed dependency for pca9685 component (#2614)
Co-authored-by: Otto Winter <otto@otto-winter.com>
Co-authored-by: Andreas <andreas.hergert@otrs.com>
2021-10-27 10:49:09 +13:00
Otto Winter
c7651dc40d Merge pull request #2613 from esphome/bump-2021.10.2
2021.10.2
2021-10-22 18:35:28 +02:00
Otto winter
eda1c471ad Bump version to 2021.10.2 2021-10-22 18:26:24 +02:00
Andreas Hergert
c7ef18fbc4 Bugfix tca9548a and idf refactor anh (#2612)
Co-authored-by: Andreas Hergert <andreas.hergert@otrs.com>
2021-10-22 18:26:23 +02:00
Otto Winter
901ec918b1 Fix ESP8266 OTA compression only starting framework v2.7.0 (#2610) 2021-10-22 18:26:23 +02:00
Otto Winter
6bdae55ee1 Fix compiler warnings and update platformio line filter (#2607) 2021-10-22 18:26:23 +02:00
Otto Winter
dfb96e4b7f Add owner to all libraries used (#2604) 2021-10-22 18:26:22 +02:00
Otto Winter
ff2c316b18 Re-raise keyboardinterrupt (#2603) 2021-10-22 18:26:22 +02:00
Otto Winter
5be52f71f9 Add OTA upload compression for ESP8266 (#2601) 2021-10-22 18:26:22 +02:00
Otto Winter
42873dd37c Bump noise-c from 0.1.3 to 0.1.4 (#2602) 2021-10-22 18:26:21 +02:00
Otto Winter
f93e7d4e3a Fix socket connection closed not detected (#2587) 2021-10-22 18:26:21 +02:00
Oxan van Leeuwen
bbcd523967 Fix validation of addressable light IDs (#2588) 2021-10-22 18:26:21 +02:00
dependabot[bot]
68cbe58d00 Bump esphome-dashboard from 20211021.0 to 20211021.1 (#2594)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-10-22 18:26:12 +02:00
Oxan van Leeuwen
115bca98f1 Fix old-style arduino_version on ESP8266 and with magic values (#2591) 2021-10-22 18:24:48 +02:00
Oxan van Leeuwen
ed0b34b2fe Fix pin/component switchup in SX1509 pin configuration (#2593) 2021-10-22 18:24:48 +02:00
Oxan van Leeuwen
ab34401421 Fix PlatformIO version for latest Arduino framework (#2590) 2021-10-22 18:24:48 +02:00
Otto Winter
eed0c18d65 Fix HeatpumpIR pin (#2585) 2021-10-22 18:24:47 +02:00
Otto Winter
e5a38ce748 Merge pull request #2580 from esphome/bump-2021.10.1
2021.10.1
2021-10-21 15:31:26 +02:00
Otto Winter
7d9d9fcf36 Fix platformio_install_deps no longer installing all lib_deps (#2584) 2021-10-21 15:29:53 +02:00
Otto Winter
f0aba6ceb2 Fix platformio version in Dockerfile doesn't match requirements (#2582) 2021-10-21 14:53:22 +02:00
Otto Winter
ab07ee57c6 Fix ESP8266 dallas GPIO16 INPUT_PULLUP (#2581) 2021-10-21 14:39:55 +02:00
Otto winter
eae3d72a4d Bump version to 2021.10.1 2021-10-21 14:23:08 +02:00
Otto Winter
7b8d826704 Fix ESP8266 OTA adds unnecessary Update library (#2579) 2021-10-21 14:23:07 +02:00
Otto Winter
e7baa42e63 Arduino global delay/millis/... symbols workaround (#2575) 2021-10-21 14:23:07 +02:00
Otto Winter
2f32833a22 Fix wifi ble coexistence check (#2573) 2021-10-21 14:23:07 +02:00
Otto Winter
f6935a4b4b Fix ESP8266 GPIO0 Pullup Validation (#2572) 2021-10-21 14:23:06 +02:00
Maurice Makaay
332c9e891b Fix MDNS for ESP8266 devices (#2571)
Co-authored-by: Maurice Makaay <account-github@makaay.nl>
Co-authored-by: Otto winter <otto@otto-winter.com>
Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
2021-10-21 14:23:06 +02:00
Jesse Hills
b91ee4847f Merge pull request #2570 from esphome/bump-2021.10.0
2021.10.0
2021-10-21 08:37:26 +13:00
Jesse Hills
625463d871 Bump version to 2021.10.0 2021-10-21 07:57:10 +13:00
Jesse Hills
6433a01e07 Merge pull request #2567 from esphome/bump-2021.10.0b11
2021.10.0b11
2021-10-21 07:47:22 +13:00
Jesse Hills
56cc31e8e7 Bump version to 2021.10.0b11 2021-10-21 07:32:27 +13:00
Otto Winter
3af297aa76 Revert nextion clang-tidy changes (#2566) 2021-10-21 07:32:27 +13:00
Otto Winter
996ec59d28 Move running process log line to debug level (#2565) 2021-10-21 07:32:26 +13:00
Jesse Hills
95593eeeab Bump esphome-dashboard to 20211021.0 (#2564) 2021-10-21 07:32:20 +13:00
Jesse Hills
dad244fb7a A few esp32_ble_server/improv fixes (#2562) 2021-10-21 07:31:55 +13:00
Jesse Hills
adb5d27d95 Merge pull request #2561 from esphome/bump-2021.10.0b10
2021.10.0b10
2021-10-20 17:28:37 +13:00
Jesse Hills
8456a8cecb Bump version to 2021.10.0b10 2021-10-20 16:39:24 +13:00
Jesse Hills
b9f66373c1 Bump esphome-dashboard to 20211020.1 (#2559) 2021-10-20 16:39:16 +13:00
Jesse Hills
9ac365feef Fix HA addon so it does not have logout button (#2558) 2021-10-20 16:38:46 +13:00
Jesse Hills
43bbd58a44 Merge pull request #2557 from esphome/bump-2021.10.0b9
2021.10.0b9
2021-10-20 11:18:40 +13:00
Jesse Hills
7feffa64f3 Bump version to 2021.10.0b9 2021-10-20 11:00:02 +13:00
Jesse Hills
ea0977abb4 Bump dashboard to 20211020.0 (#2556) 2021-10-20 10:59:53 +13:00
Jesse Hills
4c83dc7c28 Merge pull request #2555 from esphome/bump-2021.10.0b8
2021.10.0b8
2021-10-20 10:30:59 +13:00
Jesse Hills
e10ab1da78 Bump version to 2021.10.0b8 2021-10-20 10:14:30 +13:00
Martin
1b0e60374b ignore exception when not waiting for a response (#2552) 2021-10-20 10:14:30 +13:00
Oxan van Leeuwen
3a760fbb44 Fix ADC pin validation on ESP32-C3 (#2551) 2021-10-20 10:14:30 +13:00
Jesse Hills
6ef57a2973 Merge pull request #2550 from esphome/bump-2021.10.0b7
2021.10.0b7
2021-10-19 16:22:29 +13:00
Jesse Hills
3e9c7f2e9f Bump version to 2021.10.0b7 2021-10-19 15:47:31 +13:00
Jesse Hills
430598b7a1 Bump dashboard to 20211019.0 (#2549) 2021-10-19 15:47:26 +13:00
Jesse Hills
91611b09b4 Merge pull request #2545 from esphome/bump-2021.10.0b6
2021.10.0b6
2021-10-18 21:41:22 +13:00
Jesse Hills
ecd115851f Bump version to 2021.10.0b6 2021-10-18 21:26:36 +13:00
Maurice Makaay
4a1e50fed1 OTA firmware MD5 check + password support for esp-idf (#2507)
Co-authored-by: Maurice Makaay <account-github@makaay.nl>
2021-10-18 21:26:36 +13:00
Jesse Hills
d6d037047b Merge pull request #2544 from esphome/bump-2021.10.0b5
2021.10.0b5
2021-10-18 16:37:43 +13:00
Jesse Hills
b5734c2b20 Bump version to 2021.10.0b5 2021-10-18 15:31:01 +13:00
Oxan van Leeuwen
723fb7eaac Autodetect ESP32 variant (#2530)
Co-authored-by: Otto winter <otto@otto-winter.com>
2021-10-18 15:31:01 +13:00
Jesse Hills
63a9acaa19 Fix Bluetooth setup_priorities (#2458)
Co-authored-by: Otto Winter <otto@otto-winter.com>
2021-10-18 15:31:00 +13:00
Jesse Hills
0524f8c677 Fix const used for IDF recommended version (#2542) 2021-10-18 15:31:00 +13:00
Otto Winter
70b62f272e Only show timestamp for dashboard access logs (#2540) 2021-10-18 15:31:00 +13:00
Jesse Hills
f0089b7940 Merge pull request #2539 from esphome/bump-2021.10.0b4
2021.10.0b4
2021-10-17 21:17:54 +13:00
Jesse Hills
4b44280d53 Bump version to 2021.10.0b4 2021-10-17 20:34:07 +13:00
Paulus Schoutsen
f045382d20 Bump dashboard to 20211015.0 (#2525)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2021-10-17 20:34:03 +13:00
Jesse Hills
db3fa1ade7 Allow downloading all bin files from backend in dashboard (#2514)
Co-authored-by: Otto Winter <otto@otto-winter.com>
2021-10-17 20:28:43 +13:00
Oxan van Leeuwen
f83950fd75 Fix bitshift on read in ADE7953 (#2537) 2021-10-17 20:28:43 +13:00
Oxan van Leeuwen
4dd1bf920d Replace framework version_hint with source option (#2529) 2021-10-17 20:28:43 +13:00
Martin
98755f3621 Fix bug in register name definition (#2526) 2021-10-17 20:28:43 +13:00
Keith Burzinski
c3a8a044b9 Fix Nextion HTTPClient error for ESP32 (#2524) 2021-10-17 20:28:42 +13:00
Martin
15b5ea43a7 Add pressure compensation during runtime (#2493)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
2021-10-17 20:28:42 +13:00
Jesse Hills
ec683fc227 Merge pull request #2523 from esphome/bump-2021.10.0b3
2021.10.0b3
2021-10-15 10:15:26 +13:00
Jesse Hills
d4e65eb82a Bump version to 2021.10.0b3 2021-10-15 09:42:44 +13:00
Paul Monigatti
10c6601b0a Revert "Added test for bme680_bsec" (#2518)
This reverts commit 7f6a50d291b14935b17802b4dce52135fad1e49e due to BSEC library license restrictions.
2021-10-15 09:42:44 +13:00
Oxan van Leeuwen
73940bc1bd Don't define UART_SELECTION_UART2 when UART2 is unavailable (#2512) 2021-10-15 09:42:43 +13:00
Paul Monigatti
9b7fb829f9 Fix: Color modes not being correctly used in light partitions (#2513) 2021-10-15 09:42:43 +13:00
Dmitriy Lopatko
c51d8c9021 add missing include in sgp30 (#2517) 2021-10-15 09:42:43 +13:00
Paul Monigatti
d8a6dfe5ce Fix BME680_BSEC compilation issue with ESP32 (#2516) 2021-10-15 09:42:43 +13:00
Oxan van Leeuwen
5f7cef0b06 Disallow using UART2 for logger on ESP-32 variants that lack it (#2510) 2021-10-15 09:42:43 +13:00
Paul Monigatti
48ff2ffc68 Fix: Light flash not restoring previous LightState (#2383)
* Update light state when transformer has finished

* Revert writing direct to output

* Correct handling of zero-length light transformers

* Allow transformers to handle zero-length transitions, and check more boundary conditions when transitioning back to start state

* Removed log.h

* Fixed race condition between LightFlashTransformer.apply() and is_finished()

* clang-format

* Step progress from 0.0f to 1.0f at t=start_time for zero-length transforms to avoid divide-by-zero
2021-10-15 09:42:43 +13:00
Oxan van Leeuwen
b3b9ccd314 Fix light state remaining on after turn off with transition (#2509) 2021-10-15 09:42:43 +13:00
Jesse Hills
e63c7b483b Merge pull request #2505 from esphome/bump-2021.10.0b2
2021.10.0b2
2021-10-13 22:45:29 +13:00
Jesse Hills
f57980b069 Bump version to 2021.10.0b2 2021-10-13 22:30:29 +13:00
Jesse Hills
7006aa0d2a Merge branch 'dev' into beta 2021-10-13 22:11:53 +13:00
Jesse Hills
8051c1ca99 Merge pull request #2504 from esphome/bump-2021.10.0b1
2021.10.0b1
2021-10-13 21:38:41 +13:00
Jesse Hills
a779592414 Bump version to 2021.10.0b1 2021-10-13 16:40:46 +13:00
Jesse Hills
112215848d Merge branch 'dev' into bump-2021.10.0b1 2021-10-13 16:40:46 +13:00
338 changed files with 2324 additions and 5328 deletions

View File

@@ -68,6 +68,8 @@ Checks: >-
-modernize-use-nodiscard,
-mpi-*,
-objc-*,
-readability-braces-around-statements,
-readability-const-return-type,
-readability-convert-member-functions-to-static,
-readability-else-after-return,
-readability-function-cognitive-complexity,
@@ -75,6 +77,10 @@ Checks: >-
-readability-isolate-declaration,
-readability-magic-numbers,
-readability-make-member-function-const,
-readability-named-parameter,
-readability-qualified-auto,
-readability-redundant-access-specifiers,
-readability-redundant-member-init,
-readability-redundant-string-init,
-readability-uppercase-literal-suffix,
-readability-use-anyofallof,
@@ -108,8 +114,6 @@ CheckOptions:
value: 'make_unique'
- key: modernize-make-unique.MakeSmartPtrFunctionHeader
value: 'esphome/core/helpers.h'
- key: readability-braces-around-statements.ShortStatementLines
value: 2
- key: readability-identifier-naming.LocalVariableCase
value: 'lower_case'
- key: readability-identifier-naming.ClassCase
@@ -156,5 +160,3 @@ CheckOptions:
value: 'lower_case'
- key: readability-identifier-naming.VirtualMethodSuffix
value: ''
- key: readability-qualified-auto.AddConstToQualified
value: 0

View File

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

View File

@@ -2,7 +2,7 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/ambv/black
rev: 22.1.0
rev: 20.8b1
hooks:
- id: black
args:
@@ -10,7 +10,7 @@ repos:
- --quiet
files: ^((esphome|script|tests)/.+)?[^/]+\.py$
- repo: https://gitlab.com/pycqa/flake8
rev: 4.0.1
rev: 3.8.4
hooks:
- id: flake8
additional_dependencies:

View File

@@ -54,7 +54,6 @@ esphome/components/dfplayer/* @glmnet
esphome/components/dht/* @OttoWinter
esphome/components/ds1307/* @badbadc0ffee
esphome/components/dsmr/* @glmnet @zuidwijk
esphome/components/ektf2232/* @jesserockz
esphome/components/esp32/* @esphome/core
esphome/components/esp32_ble/* @jesserockz
esphome/components/esp32_ble_server/* @jesserockz
@@ -137,7 +136,6 @@ esphome/components/preferences/* @esphome/core
esphome/components/psram/* @esphome/core
esphome/components/pulse_meter/* @stevebaxter
esphome/components/pvvx_mithermometer/* @pasiz
esphome/components/qr_code/* @wjtje
esphome/components/rc522/* @glmnet
esphome/components/rc522_i2c/* @glmnet
esphome/components/rc522_spi/* @glmnet
@@ -189,7 +187,6 @@ esphome/components/tmp102/* @timsavage
esphome/components/tmp117/* @Azimath
esphome/components/tof10120/* @wstrzalka
esphome/components/toshiba/* @kbx81
esphome/components/touchscreen/* @jesserockz
esphome/components/tsl2591/* @wjcarpenter
esphome/components/tuya/binary_sensor/* @jesserockz
esphome/components/tuya/climate/* @jesserockz
@@ -200,10 +197,8 @@ esphome/components/tuya/text_sensor/* @dentra
esphome/components/uart/* @esphome/core
esphome/components/ultrasonic/* @OttoWinter
esphome/components/version/* @esphome/core
esphome/components/wake_on_lan/* @willwill2will54
esphome/components/web_server_base/* @OttoWinter
esphome/components/whirlpool/* @glmnet
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
esphome/components/xiaomi_mhoc303/* @drug123
esphome/components/xiaomi_mhoc401/* @vevsvevs
esphome/components/xpt2046/* @numo68

View File

@@ -4,5 +4,4 @@ include requirements.txt
include esphome/dashboard/templates/*.html
recursive-include esphome/dashboard/static *.ico *.js *.css *.woff* LICENSE
recursive-include esphome *.cpp *.h *.tcc
recursive-include esphome *.py.script
recursive-include esphome LICENSE.txt

View File

@@ -8,9 +8,9 @@ ARG BASEIMGTYPE=docker
FROM ghcr.io/hassio-addons/debian-base/amd64:5.2.3 AS base-hassio-amd64
FROM ghcr.io/hassio-addons/debian-base/aarch64:5.2.3 AS base-hassio-arm64
FROM ghcr.io/hassio-addons/debian-base/armv7:5.2.3 AS base-hassio-armv7
FROM debian:bullseye-20220125-slim AS base-docker-amd64
FROM debian:bullseye-20220125-slim AS base-docker-arm64
FROM debian:bullseye-20220125-slim AS base-docker-armv7
FROM debian:bullseye-20211220-slim AS base-docker-amd64
FROM debian:bullseye-20211220-slim AS base-docker-arm64
FROM debian:bullseye-20211220-slim AS base-docker-armv7
# Use TARGETARCH/TARGETVARIANT defined by docker
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
@@ -23,7 +23,7 @@ RUN \
python3=3.9.2-3 \
python3-pip=20.3.4-4 \
python3-setuptools=52.0.0-4 \
python3-pil=8.1.2+dfsg-0.3+deb11u1 \
python3-pil=8.1.2+dfsg-0.3 \
python3-cryptography=3.3.2-1 \
iputils-ping=3:20210202-1 \
git=1:2.30.2-1 \

View File

@@ -52,10 +52,10 @@ uint32_t IRAM_ATTR HOT AcDimmerDataStore::timer_intr(uint32_t now) {
this->gate_pin.digital_write(false);
}
if (time_since_zc < this->enable_time_us) {
if (time_since_zc < this->enable_time_us)
// Next event is enable, return time until that event
return this->enable_time_us - time_since_zc;
} else if (time_since_zc < disable_time_us) {
else if (time_since_zc < disable_time_us) {
// Next event is disable, return time until that event
return this->disable_time_us - time_since_zc;
}
@@ -74,10 +74,9 @@ uint32_t IRAM_ATTR HOT timer_interrupt() {
uint32_t min_dt_us = 1000;
uint32_t now = micros();
for (auto *dimmer : all_dimmers) {
if (dimmer == nullptr) {
if (dimmer == nullptr)
// no more dimmers
break;
}
uint32_t res = dimmer->timer_intr(now);
if (res != 0 && res < min_dt_us)
min_dt_us = res;
@@ -213,13 +212,12 @@ void AcDimmer::dump_config() {
LOG_PIN(" Zero-Cross Pin: ", this->zero_cross_pin_);
ESP_LOGCONFIG(TAG, " Min Power: %.1f%%", this->store_.min_power / 10.0f);
ESP_LOGCONFIG(TAG, " Init with half cycle: %s", YESNO(this->init_with_half_cycle_));
if (method_ == DIM_METHOD_LEADING_PULSE) {
if (method_ == DIM_METHOD_LEADING_PULSE)
ESP_LOGCONFIG(TAG, " Method: leading pulse");
} else if (method_ == DIM_METHOD_LEADING) {
else if (method_ == DIM_METHOD_LEADING)
ESP_LOGCONFIG(TAG, " Method: leading");
} else {
else
ESP_LOGCONFIG(TAG, " Method: trailing");
}
LOG_FLOAT_OUTPUT(this);
ESP_LOGV(TAG, " Estimated Frequency: %.3fHz", 1e6f / this->store_.cycle_time_us / 2);

View File

@@ -13,6 +13,7 @@ class AdalightLightEffect : public light::AddressableLightEffect, public uart::U
public:
AdalightLightEffect(const std::string &name);
public:
void start() override;
void stop() override;
void apply(light::AddressableLight &it, const Color &current_color) override;
@@ -29,6 +30,7 @@ class AdalightLightEffect : public light::AddressableLightEffect, public uart::U
void blank_all_leds_(light::AddressableLight &it);
Frame parse_frame_(light::AddressableLight &it);
protected:
uint32_t last_ack_{0};
uint32_t last_byte_{0};
uint32_t last_reset_{0};

View File

@@ -15,11 +15,6 @@ namespace esphome {
namespace adc {
static const char *const TAG = "adc";
// 13 bits for S3 / 12 bit for all other esp32 variants
// create a const to avoid the repated cast to enum
#ifdef USE_ESP32
static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
#endif
void ADCSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
@@ -28,14 +23,14 @@ void ADCSensor::setup() {
#endif
#ifdef USE_ESP32
adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
adc1_config_width(ADC_WIDTH_BIT_12);
if (!autorange_) {
adc1_config_channel_atten(channel_, attenuation_);
}
// load characteristics for each attenuation
for (int i = 0; i < (int) ADC_ATTEN_MAX; i++) {
auto cal_value = esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
auto cal_value = esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t) i, ADC_WIDTH_BIT_12,
1100, // default vref
&cal_characteristics_[i]);
switch (cal_value) {
@@ -70,9 +65,9 @@ void ADCSensor::dump_config() {
#ifdef USE_ESP32
LOG_PIN(" Pin: ", pin_);
if (autorange_) {
if (autorange_)
ESP_LOGCONFIG(TAG, " Attenuation: auto");
} else {
else
switch (this->attenuation_) {
case ADC_ATTEN_DB_0:
ESP_LOGCONFIG(TAG, " Attenuation: 0db (max 1.1V)");
@@ -89,7 +84,6 @@ void ADCSensor::dump_config() {
default: // This is to satisfy the unused ADC_ATTEN_MAX
break;
}
}
#endif // USE_ESP32
LOG_UPDATE_INTERVAL(this);
}

View File

@@ -24,7 +24,7 @@ void AirthingsWaveMini::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
case ESP_GATTC_SEARCH_CMPL_EVT: {
this->handle_ = 0;
auto *chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
auto chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
if (chr == nullptr) {
ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", service_uuid_.to_string().c_str(),
sensors_data_characteristic_uuid_.to_string().c_str());
@@ -56,7 +56,7 @@ void AirthingsWaveMini::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
}
void AirthingsWaveMini::read_sensors_(uint8_t *raw_value, uint16_t value_len) {
auto *value = (WaveMiniReadings *) raw_value;
auto value = (WaveMiniReadings *) raw_value;
if (sizeof(WaveMiniReadings) <= value_len) {
this->humidity_sensor_->publish_state(value->humidity / 100.0f);

View File

@@ -24,7 +24,7 @@ void AirthingsWavePlus::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
case ESP_GATTC_SEARCH_CMPL_EVT: {
this->handle_ = 0;
auto *chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
auto chr = this->parent()->get_characteristic(service_uuid_, sensors_data_characteristic_uuid_);
if (chr == nullptr) {
ESP_LOGW(TAG, "No sensor characteristic found at service %s char %s", service_uuid_.to_string().c_str(),
sensors_data_characteristic_uuid_.to_string().c_str());
@@ -56,7 +56,7 @@ void AirthingsWavePlus::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt
}
void AirthingsWavePlus::read_sensors_(uint8_t *raw_value, uint16_t value_len) {
auto *value = (WavePlusReadings *) raw_value;
auto value = (WavePlusReadings *) raw_value;
if (sizeof(WavePlusReadings) <= value_len) {
ESP_LOGD(TAG, "version = %d", value->version);

View File

@@ -19,14 +19,12 @@ uint16_t crc_16(uint8_t *ptr, uint8_t length) {
//------------------------------
while (length--) {
crc ^= *ptr++;
for (i = 0; i < 8; i++) {
for (i = 0; i < 8; i++)
if ((crc & 0x01) != 0) {
crc >>= 1;
crc ^= 0xA001;
} else {
} else
crc >>= 1;
}
}
}
return crc;
}

View File

@@ -39,7 +39,7 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
break;
}
case ESP_GATTC_SEARCH_CMPL_EVT: {
auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
auto chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
if (chr == nullptr) {
if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.",
@@ -75,14 +75,13 @@ void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_i
if (this->current_sensor_ > 0) {
if (this->illuminance_ != nullptr) {
auto *packet = this->encoder_->get_light_level_request();
auto packet = this->encoder_->get_light_level_request();
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_AUTH_REQ_NONE);
if (status) {
if (status)
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
status);
}
}
this->current_sensor_ = 0;
}
@@ -100,7 +99,7 @@ void Am43::update() {
}
if (this->current_sensor_ == 0) {
if (this->battery_ != nullptr) {
auto *packet = this->encoder_->get_battery_level_request();
auto packet = this->encoder_->get_battery_level_request();
auto status =
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);

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"

View File

@@ -25,16 +25,15 @@ void Am43Component::setup() {
void Am43Component::loop() {
if (this->node_state == espbt::ClientState::ESTABLISHED && !this->logged_in_) {
auto *packet = this->encoder_->get_send_pin_request(this->pin_);
auto packet = this->encoder_->get_send_pin_request(this->pin_);
auto status =
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
ESP_LOGI(TAG, "[%s] Logging into AM43", this->get_name().c_str());
if (status) {
if (status)
ESP_LOGW(TAG, "[%s] Error writing set_pin to device, error = %d", this->get_name().c_str(), status);
} else {
else
this->logged_in_ = true;
}
}
}
@@ -52,7 +51,7 @@ void Am43Component::control(const CoverCall &call) {
return;
}
if (call.get_stop()) {
auto *packet = this->encoder_->get_stop_request();
auto packet = this->encoder_->get_stop_request();
auto status =
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
@@ -64,7 +63,7 @@ void Am43Component::control(const CoverCall &call) {
if (this->invert_position_)
pos = 1 - pos;
auto *packet = this->encoder_->get_set_position_request(100 - (uint8_t)(pos * 100));
auto packet = this->encoder_->get_set_position_request(100 - (uint8_t)(pos * 100));
auto status =
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
@@ -81,7 +80,7 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
break;
}
case ESP_GATTC_SEARCH_CMPL_EVT: {
auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
auto chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
if (chr == nullptr) {
if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.", this->get_name().c_str());
@@ -121,7 +120,7 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (this->decoder_->has_pin_response()) {
if (this->decoder_->pin_ok_) {
ESP_LOGI(TAG, "[%s] AM43 pin accepted.", this->get_name().c_str());
auto *packet = this->encoder_->get_position_request();
auto packet = this->encoder_->get_position_request();
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
ESP_GATT_AUTH_REQ_NONE);

View File

@@ -76,6 +76,8 @@ async def to_code(config):
pos = 0
for frameIndex in range(frames):
image.seek(frameIndex)
if CONF_RESIZE in config:
image.thumbnail(config[CONF_RESIZE])
frame = image.convert("RGB")
if CONF_RESIZE in config:
frame = frame.resize([width, height])

View File

@@ -40,7 +40,7 @@ void Anova::control(const ClimateCall &call) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
}
if (call.get_target_temperature().has_value()) {
auto *pkt = this->codec_->get_set_target_temp_request(*call.get_target_temperature());
auto pkt = this->codec_->get_set_target_temp_request(*call.get_target_temperature());
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
pkt->length, pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status)
@@ -57,7 +57,7 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
break;
}
case ESP_GATTC_SEARCH_CMPL_EVT: {
auto *chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
auto chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
if (chr == nullptr) {
ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str());
@@ -114,10 +114,9 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
auto status =
esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, pkt->length,
pkt->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
if (status)
ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
status);
}
}
}
break;
@@ -134,7 +133,7 @@ void Anova::update() {
return;
if (this->current_request_ < 2) {
auto *pkt = this->codec_->get_read_device_status_request();
auto pkt = this->codec_->get_read_device_status_request();
if (this->current_request_ == 0)
this->codec_->get_set_unit_request(this->fahrenheit_ ? 'f' : 'c');
auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,

View File

@@ -36,7 +36,7 @@ class Anova : public climate::Climate, public esphome::ble_client::BLEClientNode
traits.set_visual_temperature_step(0.1);
return traits;
}
void set_unit_of_measurement(const char *unit);
void set_unit_of_measurement(const char *);
protected:
std::unique_ptr<AnovaCodec> codec_;

View File

@@ -225,10 +225,9 @@ void APDS9960::read_gesture_data_() {
uint8_t fifo_level;
APDS9960_WARNING_CHECK(this->read_byte(0xAE, &fifo_level), "Reading FIFO level failed.");
if (fifo_level == 0) {
if (fifo_level == 0)
// no data to process
return;
}
APDS9960_WARNING_CHECK(fifo_level <= 32, "FIFO level has invalid value.")

View File

@@ -95,9 +95,6 @@ message HelloResponse {
// and only exists for debugging/logging purposes.
// For example "ESPHome v1.10.0 on ESP8266"
string server_info = 3;
// The name of the server (App.get_name())
string name = 4;
}
// Message sent at the beginning of each connection to authenticate the client

View File

@@ -255,7 +255,7 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
// Shut-up about usage of deprecated speed_level_to_enum/speed_enum_to_level functions for a bit.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
bool APIConnection::send_fan_state(fan::Fan *fan) {
bool APIConnection::send_fan_state(fan::FanState *fan) {
if (!this->state_subscription_)
return false;
@@ -273,7 +273,7 @@ bool APIConnection::send_fan_state(fan::Fan *fan) {
resp.direction = static_cast<enums::FanDirection>(fan->direction);
return this->send_fan_state_response(resp);
}
bool APIConnection::send_fan_info(fan::Fan *fan) {
bool APIConnection::send_fan_info(fan::FanState *fan) {
auto traits = fan->get_traits();
ListEntitiesFanResponse msg;
msg.key = fan->get_object_id_hash();
@@ -290,7 +290,7 @@ bool APIConnection::send_fan_info(fan::Fan *fan) {
return this->send_list_entities_fan_response(msg);
}
void APIConnection::fan_command(const FanCommandRequest &msg) {
fan::Fan *fan = App.get_fan_by_key(msg.key);
fan::FanState *fan = App.get_fan_by_key(msg.key);
if (fan == nullptr)
return;
@@ -469,11 +469,10 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
if (a_switch == nullptr)
return;
if (msg.state) {
if (msg.state)
a_switch->turn_on();
} else {
else
a_switch->turn_off();
}
}
#endif
@@ -767,8 +766,6 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) {
resp.api_version_major = 1;
resp.api_version_minor = 6;
resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
resp.name = App.get_name();
this->connection_state_ = ConnectionState::CONNECTED;
return resp;
}
@@ -806,16 +803,15 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
resp.project_version = ESPHOME_PROJECT_VERSION;
#endif
#ifdef USE_WEBSERVER
resp.webserver_port = USE_WEBSERVER_PORT;
resp.webserver_port = WEBSERVER_PORT;
#endif
return resp;
}
void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) {
for (auto &it : this->parent_->get_state_subs()) {
for (auto &it : this->parent_->get_state_subs())
if (it.entity_id == msg.entity_id && it.attribute.value() == msg.attribute) {
it.callback(msg.state);
}
}
}
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
bool found = false;

View File

@@ -32,8 +32,8 @@ class APIConnection : public APIServerConnection {
void cover_command(const CoverCommandRequest &msg) override;
#endif
#ifdef USE_FAN
bool send_fan_state(fan::Fan *fan);
bool send_fan_info(fan::Fan *fan);
bool send_fan_state(fan::FanState *fan);
bool send_fan_info(fan::FanState *fan);
void fan_command(const FanCommandRequest &msg) override;
#endif
#ifdef USE_LIGHT

View File

@@ -1,9 +1,7 @@
#include "api_frame_helper.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/application.h"
#include "proto.h"
#include <cstring>
@@ -303,16 +301,9 @@ APIError APINoiseFrameHelper::state_action_() {
}
if (state_ == State::SERVER_HELLO) {
// send server hello
std::vector<uint8_t> msg;
// chosen proto
msg.push_back(0x01);
// node name, terminated by null byte
const std::string &name = App.get_name();
const uint8_t *name_ptr = reinterpret_cast<const uint8_t *>(name.c_str());
msg.insert(msg.end(), name_ptr, name_ptr + name.size() + 1);
aerr = write_frame_(msg.data(), msg.size());
uint8_t msg[1];
msg[0] = 0x01; // chosen proto
aerr = write_frame_(msg, 1);
if (aerr != APIError::OK)
return aerr;
@@ -730,12 +721,7 @@ APIError APINoiseFrameHelper::shutdown(int how) {
}
extern "C" {
// declare how noise generates random bytes (here with a good HWRNG based on the RF system)
void noise_rand_bytes(void *output, size_t len) {
if (!esphome::random_bytes(reinterpret_cast<uint8_t *>(output), len)) {
ESP_LOGE(TAG, "Failed to acquire random bytes, rebooting!");
arch_restart();
}
}
void noise_rand_bytes(void *output, size_t len) { esphome::random_bytes(reinterpret_cast<uint8_t *>(output), len); }
}
#endif // USE_API_NOISE

View File

@@ -319,10 +319,6 @@ bool HelloResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value)
this->server_info = value.as_string();
return true;
}
case 4: {
this->name = value.as_string();
return true;
}
default:
return false;
}
@@ -331,7 +327,6 @@ void HelloResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(1, this->api_version_major);
buffer.encode_uint32(2, this->api_version_minor);
buffer.encode_string(3, this->server_info);
buffer.encode_string(4, this->name);
}
#ifdef HAS_PROTO_MESSAGE_DUMP
void HelloResponse::dump_to(std::string &out) const {
@@ -350,10 +345,6 @@ void HelloResponse::dump_to(std::string &out) const {
out.append(" server_info: ");
out.append("'").append(this->server_info).append("'");
out.append("\n");
out.append(" name: ");
out.append("'").append(this->name).append("'");
out.append("\n");
out.append("}");
}
#endif

View File

@@ -147,7 +147,6 @@ class HelloResponse : public ProtoMessage {
uint32_t api_version_major{0};
uint32_t api_version_minor{0};
std::string server_info{};
std::string name{};
void encode(ProtoWriteBuffer buffer) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
void dump_to(std::string &out) const override;

View File

@@ -24,7 +24,7 @@ static const char *const TAG = "api";
void APIServer::setup() {
ESP_LOGCONFIG(TAG, "Setting up Home Assistant API server...");
this->setup_controller();
socket_ = socket::socket_ip(SOCK_STREAM, 0);
socket_ = socket::socket(AF_INET, SOCK_STREAM, 0);
if (socket_ == nullptr) {
ESP_LOGW(TAG, "Could not create socket.");
this->mark_failed();
@@ -43,16 +43,13 @@ void APIServer::setup() {
return;
}
struct sockaddr_storage server;
struct sockaddr_in server;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = ESPHOME_INADDR_ANY;
server.sin_port = htons(this->port_);
socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), htons(this->port_));
if (sl == 0) {
ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno);
this->mark_failed();
return;
}
err = socket_->bind((struct sockaddr *) &server, sl);
err = socket_->bind((struct sockaddr *) &server, sizeof(server));
if (err != 0) {
ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
this->mark_failed();
@@ -83,10 +80,9 @@ void APIServer::setup() {
if (esp32_camera::global_esp32_camera != nullptr && !esp32_camera::global_esp32_camera->is_internal()) {
esp32_camera::global_esp32_camera->add_image_callback(
[this](const std::shared_ptr<esp32_camera::CameraImage> &image) {
for (auto &c : this->clients_) {
for (auto &c : this->clients_)
if (!c->remove_)
c->send_camera_state(image);
}
});
}
#endif
@@ -192,7 +188,7 @@ void APIServer::on_cover_update(cover::Cover *obj) {
#endif
#ifdef USE_FAN
void APIServer::on_fan_update(fan::Fan *obj) {
void APIServer::on_fan_update(fan::FanState *obj) {
if (obj->is_internal())
return;
for (auto &c : this->clients_)

View File

@@ -44,7 +44,7 @@ class APIServer : public Component, public Controller {
void on_cover_update(cover::Cover *obj) override;
#endif
#ifdef USE_FAN
void on_fan_update(fan::Fan *obj) override;
void on_fan_update(fan::FanState *obj) override;
#endif
#ifdef USE_LIGHT
void on_light_update(light::LightState *obj) override;

View File

@@ -16,7 +16,7 @@ bool ListEntitiesIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_
bool ListEntitiesIterator::on_cover(cover::Cover *cover) { return this->client_->send_cover_info(cover); }
#endif
#ifdef USE_FAN
bool ListEntitiesIterator::on_fan(fan::Fan *fan) { return this->client_->send_fan_info(fan); }
bool ListEntitiesIterator::on_fan(fan::FanState *fan) { return this->client_->send_fan_info(fan); }
#endif
#ifdef USE_LIGHT
bool ListEntitiesIterator::on_light(light::LightState *light) { return this->client_->send_light_info(light); }

View File

@@ -19,7 +19,7 @@ class ListEntitiesIterator : public ComponentIterator {
bool on_cover(cover::Cover *cover) override;
#endif
#ifdef USE_FAN
bool on_fan(fan::Fan *fan) override;
bool on_fan(fan::FanState *fan) override;
#endif
#ifdef USE_LIGHT
bool on_light(light::LightState *light) override;

View File

@@ -55,19 +55,17 @@ class ProtoVarInt {
}
int32_t as_sint32() const {
// with ZigZag encoding
if (this->value_ & 1) {
if (this->value_ & 1)
return static_cast<int32_t>(~(this->value_ >> 1));
} else {
else
return static_cast<int32_t>(this->value_ >> 1);
}
}
int64_t as_sint64() const {
// with ZigZag encoding
if (this->value_ & 1) {
if (this->value_ & 1)
return static_cast<int64_t>(~(this->value_ >> 1));
} else {
else
return static_cast<int64_t>(this->value_ >> 1);
}
}
void encode(std::vector<uint8_t> &out) {
uint32_t val = this->value_;
@@ -222,11 +220,10 @@ class ProtoWriteBuffer {
}
void encode_sint32(uint32_t field_id, int32_t value, bool force = false) {
uint32_t uvalue;
if (value < 0) {
if (value < 0)
uvalue = ~(value << 1);
} else {
else
uvalue = value << 1;
}
this->encode_uint32(field_id, uvalue, force);
}
template<class C> void encode_message(uint32_t field_id, const C &value, bool force = false) {

View File

@@ -14,7 +14,7 @@ bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_
bool InitialStateIterator::on_cover(cover::Cover *cover) { return this->client_->send_cover_state(cover); }
#endif
#ifdef USE_FAN
bool InitialStateIterator::on_fan(fan::Fan *fan) { return this->client_->send_fan_state(fan); }
bool InitialStateIterator::on_fan(fan::FanState *fan) { return this->client_->send_fan_state(fan); }
#endif
#ifdef USE_LIGHT
bool InitialStateIterator::on_light(light::LightState *light) { return this->client_->send_light_state(light); }

View File

@@ -20,7 +20,7 @@ class InitialStateIterator : public ComponentIterator {
bool on_cover(cover::Cover *cover) override;
#endif
#ifdef USE_FAN
bool on_fan(fan::Fan *fan) override;
bool on_fan(fan::FanState *fan) override;
#endif
#ifdef USE_LIGHT
bool on_light(light::LightState *light) override;

View File

@@ -52,7 +52,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
protected:
virtual void execute(Ts... x) = 0;
template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...> type) {
template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...>) {
this->execute((get_execute_arg_value<Ts>(args[S]))...);
}

View File

@@ -27,7 +27,7 @@ class ComponentIterator {
virtual bool on_cover(cover::Cover *cover) = 0;
#endif
#ifdef USE_FAN
virtual bool on_fan(fan::Fan *fan) = 0;
virtual bool on_fan(fan::FanState *fan) = 0;
#endif
#ifdef USE_LIGHT
virtual bool on_light(light::LightState *light) = 0;

View File

@@ -58,11 +58,10 @@ void AS3935Component::loop() {
void AS3935Component::write_indoor(bool indoor) {
ESP_LOGV(TAG, "Setting indoor to %d", indoor);
if (indoor) {
if (indoor)
this->write_register(AFE_GAIN, GAIN_MASK, INDOOR, 1);
} else {
else
this->write_register(AFE_GAIN, GAIN_MASK, OUTDOOR, 1);
}
}
// REG0x01, bits[3:0], manufacturer default: 0010 (2).
// This setting determines the threshold for events that trigger the

View File

@@ -97,7 +97,7 @@ void BalluClimate::transmit_state() {
// Send code
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(38000);
@@ -130,10 +130,10 @@ bool BalluClimate::on_receive(remote_base::RemoteReceiveData data) {
for (int i = 0; i < BALLU_STATE_LENGTH; i++) {
// Read bit
for (int j = 0; j < 8; j++) {
if (data.expect_item(BALLU_BIT_MARK, BALLU_ONE_SPACE)) {
if (data.expect_item(BALLU_BIT_MARK, BALLU_ONE_SPACE))
remote_state[i] |= 1 << j;
} else if (!data.expect_item(BALLU_BIT_MARK, BALLU_ZERO_SPACE)) {
else if (!data.expect_item(BALLU_BIT_MARK, BALLU_ZERO_SPACE)) {
ESP_LOGV(TAG, "Byte %d bit %d fail", i, j);
return false;
}

View File

@@ -21,13 +21,12 @@ void BangBangClimate::setup() {
restore->to_call(this).perform();
} else {
// restore from defaults, change_away handles those for us
if (supports_cool_ && supports_heat_) {
if (supports_cool_ && supports_heat_)
this->mode = climate::CLIMATE_MODE_HEAT_COOL;
} else if (supports_cool_) {
else if (supports_cool_)
this->mode = climate::CLIMATE_MODE_COOL;
} else if (supports_heat_) {
else if (supports_heat_)
this->mode = climate::CLIMATE_MODE_HEAT;
}
this->change_away_(false);
}
}
@@ -57,12 +56,11 @@ climate::ClimateTraits BangBangClimate::traits() {
if (supports_cool_ && supports_heat_)
traits.add_supported_mode(climate::CLIMATE_MODE_HEAT_COOL);
traits.set_supports_two_point_target_temperature(true);
if (supports_away_) {
if (supports_away_)
traits.set_supported_presets({
climate::CLIMATE_PRESET_HOME,
climate::CLIMATE_PRESET_AWAY,
});
}
traits.set_supports_action(true);
return traits;
}
@@ -84,19 +82,17 @@ void BangBangClimate::compute_state_() {
if (too_cold) {
// too cold -> enable heating if possible and enabled, else idle
if (this->supports_heat_ &&
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_HEAT)) {
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_HEAT))
target_action = climate::CLIMATE_ACTION_HEATING;
} else {
else
target_action = climate::CLIMATE_ACTION_IDLE;
}
} else if (too_hot) {
// too hot -> enable cooling if possible and enabled, else idle
if (this->supports_cool_ &&
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_COOL)) {
(this->mode == climate::CLIMATE_MODE_HEAT_COOL || this->mode == climate::CLIMATE_MODE_COOL))
target_action = climate::CLIMATE_ACTION_COOLING;
} else {
else
target_action = climate::CLIMATE_ACTION_IDLE;
}
} else {
// neither too hot nor too cold -> in range
if (this->supports_cool_ && this->supports_heat_ && this->mode == climate::CLIMATE_MODE_HEAT_COOL) {
@@ -111,10 +107,9 @@ void BangBangClimate::compute_state_() {
this->switch_to_action_(target_action);
}
void BangBangClimate::switch_to_action_(climate::ClimateAction action) {
if (action == this->action) {
if (action == this->action)
// already in target mode
return;
}
if ((action == climate::CLIMATE_ACTION_OFF && this->action == climate::CLIMATE_ACTION_IDLE) ||
(action == climate::CLIMATE_ACTION_IDLE && this->action == climate::CLIMATE_ACTION_OFF)) {

View File

@@ -9,7 +9,7 @@ from esphome.const import (
)
from .. import binary_ns
BinaryFan = binary_ns.class_("BinaryFan", fan.Fan, cg.Component)
BinaryFan = binary_ns.class_("BinaryFan", cg.Component)
CONFIG_SCHEMA = fan.FAN_SCHEMA.extend(
{
@@ -24,8 +24,9 @@ CONFIG_SCHEMA = fan.FAN_SCHEMA.extend(
async def to_code(config):
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
await cg.register_component(var, config)
await fan.register_fan(var, config)
fan_ = await fan.create_fan_state(config)
cg.add(var.set_fan(fan_))
output_ = await cg.get_variable(config[CONF_OUTPUT])
cg.add(var.set_output(output_))

View File

@@ -6,35 +6,59 @@ namespace binary {
static const char *const TAG = "binary.fan";
void BinaryFan::setup() {
auto restore = this->restore_state_();
if (restore.has_value()) {
restore->apply(*this);
this->write_state_();
void binary::BinaryFan::dump_config() {
ESP_LOGCONFIG(TAG, "Fan '%s':", this->fan_->get_name().c_str());
if (this->fan_->get_traits().supports_oscillation()) {
ESP_LOGCONFIG(TAG, " Oscillation: YES");
}
if (this->fan_->get_traits().supports_direction()) {
ESP_LOGCONFIG(TAG, " Direction: YES");
}
}
void BinaryFan::dump_config() { LOG_FAN("", "Binary Fan", this); }
fan::FanTraits BinaryFan::get_traits() {
return fan::FanTraits(this->oscillating_ != nullptr, false, this->direction_ != nullptr, 0);
void BinaryFan::setup() {
auto traits = fan::FanTraits(this->oscillating_ != nullptr, false, this->direction_ != nullptr, 0);
this->fan_->set_traits(traits);
this->fan_->add_on_state_callback([this]() { this->next_update_ = true; });
}
void BinaryFan::control(const fan::FanCall &call) {
if (call.get_state().has_value())
this->state = *call.get_state();
if (call.get_oscillating().has_value())
this->oscillating = *call.get_oscillating();
if (call.get_direction().has_value())
this->direction = *call.get_direction();
void BinaryFan::loop() {
if (!this->next_update_) {
return;
}
this->next_update_ = false;
this->write_state_();
this->publish_state();
}
void BinaryFan::write_state_() {
this->output_->set_state(this->state);
if (this->oscillating_ != nullptr)
this->oscillating_->set_state(this->oscillating);
if (this->direction_ != nullptr)
this->direction_->set_state(this->direction == fan::FanDirection::REVERSE);
{
bool enable = this->fan_->state;
if (enable)
this->output_->turn_on();
else
this->output_->turn_off();
ESP_LOGD(TAG, "Setting binary state: %s", ONOFF(enable));
}
if (this->oscillating_ != nullptr) {
bool enable = this->fan_->oscillating;
if (enable) {
this->oscillating_->turn_on();
} else {
this->oscillating_->turn_off();
}
ESP_LOGD(TAG, "Setting oscillation: %s", ONOFF(enable));
}
if (this->direction_ != nullptr) {
bool enable = this->fan_->direction == fan::FAN_DIRECTION_REVERSE;
if (enable) {
this->direction_->turn_on();
} else {
this->direction_->turn_off();
}
ESP_LOGD(TAG, "Setting reverse direction: %s", ONOFF(enable));
}
}
// We need a higher priority than the FanState component to make sure that the traits are set
// when that component sets itself up.
float BinaryFan::get_setup_priority() const { return fan_->get_setup_priority() + 1.0f; }
} // namespace binary
} // namespace esphome

View File

@@ -2,29 +2,28 @@
#include "esphome/core/component.h"
#include "esphome/components/output/binary_output.h"
#include "esphome/components/fan/fan.h"
#include "esphome/components/fan/fan_state.h"
namespace esphome {
namespace binary {
class BinaryFan : public Component, public fan::Fan {
class BinaryFan : public Component {
public:
void set_fan(fan::FanState *fan) { fan_ = fan; }
void set_output(output::BinaryOutput *output) { output_ = output; }
void setup() override;
void loop() override;
void dump_config() override;
void set_output(output::BinaryOutput *output) { this->output_ = output; }
float get_setup_priority() const override;
void set_oscillating(output::BinaryOutput *oscillating) { this->oscillating_ = oscillating; }
void set_direction(output::BinaryOutput *direction) { this->direction_ = direction; }
fan::FanTraits get_traits() override;
protected:
void control(const fan::FanCall &call) override;
void write_state_();
fan::FanState *fan_;
output::BinaryOutput *output_;
output::BinaryOutput *oscillating_{nullptr};
output::BinaryOutput *direction_{nullptr};
bool next_update_{true};
};
} // namespace binary

View File

@@ -74,10 +74,8 @@ class BinarySensor : public EntityBase {
// ========== OVERRIDE METHODS ==========
// (You'll only need this when creating your own custom binary sensor)
/** Override this to set the default device class.
*
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
*/
/// Get the default device class for this sensor, or empty string for no default.
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
virtual std::string device_class();
protected:

View File

@@ -65,7 +65,7 @@ void BL0940::update() {
}
void BL0940::setup() {
for (auto *i : BL0940_INIT) {
for (auto i : BL0940_INIT) {
this->write_array(i, 6);
delay(1);
}

View File

@@ -167,7 +167,7 @@ void BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t es
break;
}
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
auto *descr = this->get_config_descriptor(param->reg_for_notify.handle);
auto descr = this->get_config_descriptor(param->reg_for_notify.handle);
if (descr == nullptr) {
ESP_LOGW(TAG, "No descriptor found for notify of handle 0x%x", param->reg_for_notify.handle);
break;
@@ -252,17 +252,16 @@ float BLEClient::parse_char_value(uint8_t *value, uint16_t length) {
}
BLEService *BLEClient::get_service(espbt::ESPBTUUID uuid) {
for (auto *svc : this->services_) {
for (auto svc : this->services_)
if (svc->uuid == uuid)
return svc;
}
return nullptr;
}
BLEService *BLEClient::get_service(uint16_t uuid) { return this->get_service(espbt::ESPBTUUID::from_uint16(uuid)); }
BLECharacteristic *BLEClient::get_characteristic(espbt::ESPBTUUID service, espbt::ESPBTUUID chr) {
auto *svc = this->get_service(service);
auto svc = this->get_service(service);
if (svc == nullptr)
return nullptr;
return svc->get_characteristic(chr);
@@ -273,24 +272,19 @@ BLECharacteristic *BLEClient::get_characteristic(uint16_t service, uint16_t chr)
}
BLEDescriptor *BLEClient::get_config_descriptor(uint16_t handle) {
for (auto &svc : this->services_) {
for (auto &chr : svc->characteristics) {
if (chr->handle == handle) {
for (auto &desc : chr->descriptors) {
for (auto &svc : this->services_)
for (auto &chr : svc->characteristics)
if (chr->handle == handle)
for (auto &desc : chr->descriptors)
if (desc->uuid == espbt::ESPBTUUID::from_uint16(0x2902))
return desc;
}
}
}
}
return nullptr;
}
BLECharacteristic *BLEService::get_characteristic(espbt::ESPBTUUID uuid) {
for (auto &chr : this->characteristics) {
for (auto &chr : this->characteristics)
if (chr->uuid == uuid)
return chr;
}
return nullptr;
}
@@ -299,10 +293,10 @@ BLECharacteristic *BLEService::get_characteristic(uint16_t uuid) {
}
BLEDescriptor *BLEClient::get_descriptor(espbt::ESPBTUUID service, espbt::ESPBTUUID chr, espbt::ESPBTUUID descr) {
auto *svc = this->get_service(service);
auto svc = this->get_service(service);
if (svc == nullptr)
return nullptr;
auto *ch = svc->get_characteristic(chr);
auto ch = svc->get_characteristic(chr);
if (ch == nullptr)
return nullptr;
return ch->get_descriptor(descr);
@@ -385,10 +379,9 @@ void BLECharacteristic::parse_descriptors() {
}
BLEDescriptor *BLECharacteristic::get_descriptor(espbt::ESPBTUUID uuid) {
for (auto &desc : this->descriptors) {
for (auto &desc : this->descriptors)
if (desc->uuid == uuid)
return desc;
}
return nullptr;
}
BLEDescriptor *BLECharacteristic::get_descriptor(uint16_t uuid) {
@@ -396,7 +389,7 @@ BLEDescriptor *BLECharacteristic::get_descriptor(uint16_t uuid) {
}
void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size) {
auto *client = this->service->client;
auto client = this->service->client;
auto status = esp_ble_gattc_write_char(client->gattc_if, client->conn_id, this->handle, new_val_size, new_val,
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {

View File

@@ -126,10 +126,9 @@ class BLEClient : public espbt::ESPBTClient, public Component {
bool all_nodes_established_() {
if (this->state() != espbt::ClientState::ESTABLISHED)
return false;
for (auto &node : nodes_) {
for (auto &node : nodes_)
if (node->node_state != espbt::ClientState::ESTABLISHED)
return false;
}
return true;
}

View File

@@ -32,7 +32,7 @@ void BLEBinaryOutput::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
break;
}
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
auto chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
if (chr == nullptr) {
ESP_LOGW(TAG, "[%s] Characteristic not found.", this->char_uuid_.to_string().c_str());
break;
@@ -54,7 +54,7 @@ void BLEBinaryOutput::write_state(bool state) {
return;
}
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
auto chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
if (chr == nullptr) {
ESP_LOGW(TAG, "[%s] Characteristic not found. State update can not be written.",
this->char_uuid_.to_string().c_str());

View File

@@ -43,7 +43,7 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
}
case ESP_GATTC_SEARCH_CMPL_EVT: {
this->handle = 0;
auto *chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
auto chr = this->parent()->get_characteristic(this->service_uuid_, this->char_uuid_);
if (chr == nullptr) {
this->status_set_warning();
this->publish_state(NAN);
@@ -53,7 +53,7 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
}
this->handle = chr->handle;
if (this->descr_uuid_.get_uuid().len > 0) {
auto *descr = chr->get_descriptor(this->descr_uuid_);
auto descr = chr->get_descriptor(this->descr_uuid_);
if (descr == nullptr) {
this->status_set_warning();
this->publish_state(NAN);

View File

@@ -214,10 +214,9 @@ void BME280Component::update() {
float BME280Component::read_temperature_(const uint8_t *data, int32_t *t_fine) {
int32_t adc = ((data[3] & 0xFF) << 16) | ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
adc >>= 4;
if (adc == 0x80000) {
if (adc == 0x80000)
// temperature was disabled
return NAN;
}
const int32_t t1 = this->calibration_.t1;
const int32_t t2 = this->calibration_.t2;
@@ -234,10 +233,9 @@ float BME280Component::read_temperature_(const uint8_t *data, int32_t *t_fine) {
float BME280Component::read_pressure_(const uint8_t *data, int32_t t_fine) {
int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
adc >>= 4;
if (adc == 0x80000) {
if (adc == 0x80000)
// pressure was disabled
return NAN;
}
const int64_t p1 = this->calibration_.p1;
const int64_t p2 = this->calibration_.p2;
const int64_t p3 = this->calibration_.p3;

View File

@@ -95,7 +95,7 @@ void BME680Component::setup() {
this->calibration_.t3 = cal1[3];
this->calibration_.h1 = cal2[2] << 4 | (cal2[1] & 0x0F);
this->calibration_.h2 = cal2[0] << 4 | cal2[1] >> 4;
this->calibration_.h2 = cal2[0] << 4 | cal2[1];
this->calibration_.h3 = cal2[3];
this->calibration_.h4 = cal2[4];
this->calibration_.h5 = cal2[5];
@@ -420,11 +420,10 @@ float BME680Component::calc_humidity_(uint16_t raw_humidity) {
calc_hum = var2 + (var3 + var4 * temp_comp) * var2 * var2;
if (calc_hum > 100.0f) {
if (calc_hum > 100.0f)
calc_hum = 100.0f;
} else if (calc_hum < 0.0f) {
else if (calc_hum < 0.0f)
calc_hum = 0.0f;
}
return calc_hum;
}

View File

@@ -161,10 +161,9 @@ float BMP280Component::read_temperature_(int32_t *t_fine) {
return NAN;
int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
adc >>= 4;
if (adc == 0x80000) {
if (adc == 0x80000)
// temperature was disabled
return NAN;
}
const int32_t t1 = this->calibration_.t1;
const int32_t t2 = this->calibration_.t2;
@@ -184,10 +183,9 @@ float BMP280Component::read_pressure_(int32_t t_fine) {
return NAN;
int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
adc >>= 4;
if (adc == 0x80000) {
if (adc == 0x80000)
// pressure was disabled
return NAN;
}
const int64_t p1 = this->calibration_.p1;
const int64_t p2 = this->calibration_.p2;
const int64_t p3 = this->calibration_.p3;

View File

@@ -75,7 +75,7 @@ void Canbus::loop() {
}
// fire all triggers
for (auto *trigger : this->triggers_) {
for (auto trigger : this->triggers_) {
if ((trigger->can_id_ == can_message.can_id) && (trigger->use_extended_id_ == can_message.use_extended_id)) {
trigger->trigger(data);
}

View File

@@ -39,15 +39,14 @@ void CCS811Component::setup() {
// set MEAS_MODE (page 5)
uint8_t meas_mode = 0;
uint32_t interval = this->get_update_interval();
if (interval >= 60 * 1000) {
if (interval >= 60 * 1000)
meas_mode = 3 << 4; // sensor takes a reading every 60 seconds
} else if (interval >= 10 * 1000) {
else if (interval >= 10 * 1000)
meas_mode = 2 << 4; // sensor takes a reading every 10 seconds
} else if (interval >= 1 * 1000) {
else if (interval >= 1 * 1000)
meas_mode = 1 << 4; // sensor takes a reading every second
} else {
else
meas_mode = 4 << 4; // sensor takes a reading every 250ms
}
CHECKED_IO(this->write_byte(0x01, meas_mode))

View File

@@ -6,9 +6,8 @@ from esphome.const import (
CONF_ID,
)
AUTO_LOAD = ["sensor", "voltage_sampler"]
CODEOWNERS = ["@asoehlke"]
MULTI_CONF = True
AUTO_LOAD = ["sensor", "voltage_sampler"]
cd74hc4067_ns = cg.esphome_ns.namespace("cd74hc4067")

View File

@@ -65,7 +65,7 @@ class ClimateTraits {
ESPDEPRECATED("This method is deprecated, use set_supported_modes() instead", "v1.20")
void set_supports_dry_mode(bool supports_dry_mode) { set_mode_support_(CLIMATE_MODE_DRY, supports_dry_mode); }
bool supports_mode(ClimateMode mode) const { return supported_modes_.count(mode); }
std::set<ClimateMode> get_supported_modes() const { return supported_modes_; }
const std::set<ClimateMode> get_supported_modes() const { return supported_modes_; }
void set_supports_action(bool supports_action) { supports_action_ = supports_action; }
bool get_supports_action() const { return supports_action_; }
@@ -93,7 +93,7 @@ class ClimateTraits {
void set_supports_fan_mode_diffuse(bool supported) { set_fan_mode_support_(CLIMATE_FAN_DIFFUSE, supported); }
bool supports_fan_mode(ClimateFanMode fan_mode) const { return supported_fan_modes_.count(fan_mode); }
bool get_supports_fan_modes() const { return !supported_fan_modes_.empty() || !supported_custom_fan_modes_.empty(); }
std::set<ClimateFanMode> get_supported_fan_modes() const { return supported_fan_modes_; }
const std::set<ClimateFanMode> get_supported_fan_modes() const { return supported_fan_modes_; }
void set_supported_custom_fan_modes(std::set<std::string> supported_custom_fan_modes) {
supported_custom_fan_modes_ = std::move(supported_custom_fan_modes);
@@ -141,7 +141,7 @@ class ClimateTraits {
}
bool supports_swing_mode(ClimateSwingMode swing_mode) const { return supported_swing_modes_.count(swing_mode); }
bool get_supports_swing_modes() const { return !supported_swing_modes_.empty(); }
std::set<ClimateSwingMode> get_supported_swing_modes() { return supported_swing_modes_; }
const std::set<ClimateSwingMode> get_supported_swing_modes() { return supported_swing_modes_; }
float get_visual_min_temperature() const { return visual_min_temperature_; }
void set_visual_min_temperature(float visual_min_temperature) { visual_min_temperature_ = visual_min_temperature; }

View File

@@ -137,11 +137,11 @@ bool LgIrClimate::on_receive(remote_base::RemoteReceiveData data) {
this->swing_mode =
this->swing_mode == climate::CLIMATE_SWING_OFF ? climate::CLIMATE_SWING_VERTICAL : climate::CLIMATE_SWING_OFF;
} else {
if ((remote_state & COMMAND_MASK) == COMMAND_AUTO) {
if ((remote_state & COMMAND_MASK) == COMMAND_AUTO)
this->mode = climate::CLIMATE_MODE_HEAT_COOL;
} else if ((remote_state & COMMAND_MASK) == COMMAND_DRY_FAN) {
else if ((remote_state & COMMAND_MASK) == COMMAND_DRY_FAN)
this->mode = climate::CLIMATE_MODE_DRY;
} else if ((remote_state & COMMAND_MASK) == COMMAND_HEAT) {
else if ((remote_state & COMMAND_MASK) == COMMAND_HEAT) {
this->mode = climate::CLIMATE_MODE_HEAT;
} else {
this->mode = climate::CLIMATE_MODE_COOL;
@@ -156,15 +156,14 @@ bool LgIrClimate::on_receive(remote_base::RemoteReceiveData data) {
this->fan_mode = climate::CLIMATE_FAN_AUTO;
} else if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_HEAT ||
this->mode == climate::CLIMATE_MODE_DRY) {
if ((remote_state & FAN_MASK) == FAN_AUTO) {
if ((remote_state & FAN_MASK) == FAN_AUTO)
this->fan_mode = climate::CLIMATE_FAN_AUTO;
} else if ((remote_state & FAN_MASK) == FAN_MIN) {
else if ((remote_state & FAN_MASK) == FAN_MIN)
this->fan_mode = climate::CLIMATE_FAN_LOW;
} else if ((remote_state & FAN_MASK) == FAN_MED) {
else if ((remote_state & FAN_MASK) == FAN_MED)
this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
} else if ((remote_state & FAN_MASK) == FAN_MAX) {
else if ((remote_state & FAN_MASK) == FAN_MAX)
this->fan_mode = climate::CLIMATE_FAN_HIGH;
}
}
}
this->publish_state();
@@ -176,7 +175,7 @@ void LgIrClimate::transmit_(uint32_t value) {
ESP_LOGD(TAG, "Sending climate_lg_ir code: 0x%02X", value);
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(38000);
data->reserve(2 + BITS * 2u);

View File

@@ -104,7 +104,7 @@ void CoolixClimate::transmit_state() {
ESP_LOGV(TAG, "Sending coolix code: 0x%06X", remote_state);
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
remote_base::CoolixProtocol().encode(data, remote_state);
transmit.perform();
}
@@ -125,37 +125,34 @@ bool CoolixClimate::on_coolix(climate::Climate *parent, remote_base::RemoteRecei
parent->swing_mode =
parent->swing_mode == climate::CLIMATE_SWING_OFF ? climate::CLIMATE_SWING_VERTICAL : climate::CLIMATE_SWING_OFF;
} else {
if ((remote_state & COOLIX_MODE_MASK) == COOLIX_HEAT) {
if ((remote_state & COOLIX_MODE_MASK) == COOLIX_HEAT)
parent->mode = climate::CLIMATE_MODE_HEAT;
} else if ((remote_state & COOLIX_MODE_MASK) == COOLIX_AUTO) {
else if ((remote_state & COOLIX_MODE_MASK) == COOLIX_AUTO)
parent->mode = climate::CLIMATE_MODE_HEAT_COOL;
} else if ((remote_state & COOLIX_MODE_MASK) == COOLIX_DRY_FAN) {
if ((remote_state & COOLIX_FAN_MASK) == COOLIX_FAN_MODE_AUTO_DRY) {
else if ((remote_state & COOLIX_MODE_MASK) == COOLIX_DRY_FAN) {
if ((remote_state & COOLIX_FAN_MASK) == COOLIX_FAN_MODE_AUTO_DRY)
parent->mode = climate::CLIMATE_MODE_DRY;
} else {
else
parent->mode = climate::CLIMATE_MODE_FAN_ONLY;
}
} else
parent->mode = climate::CLIMATE_MODE_COOL;
// Fan Speed
if ((remote_state & COOLIX_FAN_AUTO) == COOLIX_FAN_AUTO || parent->mode == climate::CLIMATE_MODE_HEAT_COOL ||
parent->mode == climate::CLIMATE_MODE_DRY) {
parent->mode == climate::CLIMATE_MODE_DRY)
parent->fan_mode = climate::CLIMATE_FAN_AUTO;
} else if ((remote_state & COOLIX_FAN_MIN) == COOLIX_FAN_MIN) {
else if ((remote_state & COOLIX_FAN_MIN) == COOLIX_FAN_MIN)
parent->fan_mode = climate::CLIMATE_FAN_LOW;
} else if ((remote_state & COOLIX_FAN_MED) == COOLIX_FAN_MED) {
else if ((remote_state & COOLIX_FAN_MED) == COOLIX_FAN_MED)
parent->fan_mode = climate::CLIMATE_FAN_MEDIUM;
} else if ((remote_state & COOLIX_FAN_MAX) == COOLIX_FAN_MAX) {
else if ((remote_state & COOLIX_FAN_MAX) == COOLIX_FAN_MAX)
parent->fan_mode = climate::CLIMATE_FAN_HIGH;
}
// Temperature
uint8_t temperature_code = remote_state & COOLIX_TEMP_MASK;
for (uint8_t i = 0; i < COOLIX_TEMP_RANGE; i++) {
for (uint8_t i = 0; i < COOLIX_TEMP_RANGE; i++)
if (COOLIX_TEMP_MAP[i] == temperature_code)
parent->target_temperature = i + COOLIX_TEMP_MIN;
}
}
parent->publish_state();

View File

@@ -169,11 +169,7 @@ class Cover : public EntityBase {
friend CoverCall;
virtual void control(const CoverCall &call) = 0;
/** Override this to set the default device class.
*
* @deprecated This method is deprecated, set the property during config validation instead. (2022.1)
*/
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
virtual std::string device_class();
optional<CoverRestoreState> restore_state_();

View File

@@ -49,8 +49,8 @@ def validate_config(config):
if current_gain == 0.0 or voltage_gain == 0.0:
raise cv.Invalid("The gains can't be zero")
max_energy = (0.25 * 0.25 / 3600 / (2**-4)) / (voltage_gain * current_gain)
min_energy = (0.25 * 0.25 / 3600 / (2**18)) / (voltage_gain * current_gain)
max_energy = (0.25 * 0.25 / 3600 / (2 ** -4)) / (voltage_gain * current_gain)
min_energy = (0.25 * 0.25 / 3600 / (2 ** 18)) / (voltage_gain * current_gain)
mech_min_energy = (0.25 * 0.25 / 3600 / 7.8) / (voltage_gain * current_gain)
if pulse_energy < min_energy or pulse_energy > max_energy:
raise cv.Invalid(

View File

@@ -23,7 +23,7 @@ void DaikinClimate::transmit_state() {
}
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(DAIKIN_IR_FREQUENCY);
data->mark(DAIKIN_HEADER_MARK);
@@ -175,15 +175,14 @@ bool DaikinClimate::parse_state_frame_(const uint8_t frame[]) {
}
uint8_t fan_mode = frame[8];
uint8_t swing_mode = frame[9];
if (fan_mode & 0xF && swing_mode & 0xF) {
if (fan_mode & 0xF && swing_mode & 0xF)
this->swing_mode = climate::CLIMATE_SWING_BOTH;
} else if (fan_mode & 0xF) {
else if (fan_mode & 0xF)
this->swing_mode = climate::CLIMATE_SWING_VERTICAL;
} else if (swing_mode & 0xF) {
else if (swing_mode & 0xF)
this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
} else {
else
this->swing_mode = climate::CLIMATE_SWING_OFF;
}
switch (fan_mode & 0xF0) {
case DAIKIN_FAN_1:
case DAIKIN_FAN_2:
@@ -213,9 +212,9 @@ bool DaikinClimate::on_receive(remote_base::RemoteReceiveData data) {
for (uint8_t pos = 0; pos < DAIKIN_STATE_FRAME_SIZE; pos++) {
uint8_t byte = 0;
for (int8_t bit = 0; bit < 8; bit++) {
if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) {
if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE))
byte |= 1 << bit;
} else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
return false;
}
}

View File

@@ -52,7 +52,7 @@ void DallasComponent::setup() {
this->found_sensors_.push_back(address);
}
for (auto *sensor : this->sensors_) {
for (auto sensor : this->sensors_) {
if (sensor->get_index().has_value()) {
if (*sensor->get_index() >= this->found_sensors_.size()) {
this->status_set_error();
@@ -235,7 +235,7 @@ float DallasTemperatureSensor::get_temp_c() {
return temp / 128.0f;
}
std::string DallasTemperatureSensor::unique_id() { return "dallas-" + str_lower_case(format_hex(this->address_)); }
std::string DallasTemperatureSensor::unique_id() { return "dallas-" + str_upper_case(format_hex(this->address_)); }
} // namespace dallas
} // namespace esphome

View File

@@ -145,10 +145,9 @@ uint64_t ESPOneWire::search() {
// read its complement
bool cmp_id_bit = this->read_bit();
if (id_bit && cmp_id_bit) {
if (id_bit && cmp_id_bit)
// No devices participating in search
break;
}
bool branch;
@@ -171,13 +170,12 @@ uint64_t ESPOneWire::search() {
}
}
if (branch) {
if (branch)
// set bit
this->rom_number8_()[rom_byte_number] |= rom_byte_mask;
} else {
else
// clear bit
this->rom_number8_()[rom_byte_number] &= ~rom_byte_mask;
}
// choose/announce branch
this->write_bit(branch);
@@ -192,10 +190,9 @@ uint64_t ESPOneWire::search() {
if (id_bit_number >= 65) {
this->last_discrepancy_ = last_zero;
if (this->last_discrepancy_ == 0) {
if (this->last_discrepancy_ == 0)
// we're at root and have no choices left, so this was the last one.
this->last_device_flag_ = true;
}
search_result = true;
}

View File

@@ -1,68 +1,19 @@
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.components import sensor, text_sensor
from esphome.const import (
CONF_ID,
CONF_DEVICE,
CONF_FREE,
CONF_FRAGMENTATION,
CONF_BLOCK,
CONF_LOOP_TIME,
UNIT_MILLISECOND,
UNIT_PERCENT,
UNIT_BYTES,
ICON_COUNTER,
ICON_TIMER,
)
from esphome.const import CONF_ID
CODEOWNERS = ["@OttoWinter"]
DEPENDENCIES = ["logger"]
debug_ns = cg.esphome_ns.namespace("debug")
DebugComponent = debug_ns.class_("DebugComponent", cg.PollingComponent)
DebugComponent = debug_ns.class_("DebugComponent", cg.Component)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(DebugComponent),
cv.Optional(CONF_DEVICE): text_sensor.TEXT_SENSOR_SCHEMA.extend(
{cv.GenerateID(): cv.declare_id(text_sensor.TextSensor)}
),
cv.Optional(CONF_FREE): sensor.sensor_schema(UNIT_BYTES, ICON_COUNTER, 0),
cv.Optional(CONF_BLOCK): sensor.sensor_schema(UNIT_BYTES, ICON_COUNTER, 0),
cv.Optional(CONF_FRAGMENTATION): cv.All(
cv.only_on_esp8266,
cv.require_framework_version(esp8266_arduino=cv.Version(2, 5, 2)),
sensor.sensor_schema(UNIT_PERCENT, ICON_COUNTER, 1),
),
cv.Optional(CONF_LOOP_TIME): sensor.sensor_schema(
UNIT_MILLISECOND, ICON_TIMER, 1
),
}
).extend(cv.polling_component_schema("60s"))
).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
if CONF_DEVICE in config:
sens = cg.new_Pvariable(config[CONF_DEVICE][CONF_ID])
await text_sensor.register_text_sensor(sens, config[CONF_DEVICE])
cg.add(var.set_device_info_sensor(sens))
if CONF_FREE in config:
sens = await sensor.new_sensor(config[CONF_FREE])
cg.add(var.set_free_sensor(sens))
if CONF_BLOCK in config:
sens = await sensor.new_sensor(config[CONF_BLOCK])
cg.add(var.set_block_sensor(sens))
if CONF_FRAGMENTATION in config:
sens = await sensor.new_sensor(config[CONF_FRAGMENTATION])
cg.add(var.set_fragmentation_sensor(sens))
if CONF_LOOP_TIME in config:
sens = await sensor.new_sensor(config[CONF_LOOP_TIME])
cg.add(var.set_loop_time_sensor(sens))

View File

@@ -1,23 +1,21 @@
#include "debug_component.h"
#include <algorithm>
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/defines.h"
#include "esphome/core/version.h"
#ifdef USE_ESP32
#ifdef USE_ESP_IDF
#include <esp_heap_caps.h>
#include <esp_system.h>
#endif
#ifdef USE_ESP32
#if ESP_IDF_VERSION_MAJOR >= 4
#include <esp32/rom/rtc.h>
#else
#include <rom/rtc.h>
#endif
#endif // USE_ESP32
#endif
#ifdef USE_ARDUINO
#include <Esp.h>
@@ -28,36 +26,19 @@ namespace debug {
static const char *const TAG = "debug";
static uint32_t get_free_heap() {
#if defined(USE_ESP8266)
return ESP.getFreeHeap(); // NOLINT(readability-static-accessed-through-instance)
#elif defined(USE_ESP32)
return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
#endif
}
void DebugComponent::dump_config() {
std::string device_info;
device_info.reserve(256);
#ifndef ESPHOME_LOG_HAS_DEBUG
ESP_LOGE(TAG, "Debug Component requires debug log level!");
this->status_set_error();
return;
#endif
ESP_LOGCONFIG(TAG, "Debug component:");
LOG_TEXT_SENSOR(" ", "Device info", this->device_info_);
LOG_SENSOR(" ", "Free space on heap", this->free_sensor_);
LOG_SENSOR(" ", "Largest free heap block", this->block_sensor_);
#if defined(USE_ESP8266) && ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
LOG_SENSOR(" ", "Heap fragmentation", this->fragmentation_sensor_);
#endif
ESP_LOGD(TAG, "ESPHome version %s", ESPHOME_VERSION);
device_info += ESPHOME_VERSION;
this->free_heap_ = get_free_heap();
#ifdef USE_ARDUINO
this->free_heap_ = ESP.getFreeHeap(); // NOLINT(readability-static-accessed-through-instance)
#elif defined(USE_ESP_IDF)
this->free_heap_ = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
#endif
ESP_LOGD(TAG, "Free Heap Size: %u bytes", this->free_heap_);
#ifdef USE_ARDUINO
@@ -86,12 +67,9 @@ void DebugComponent::dump_config() {
default:
flash_mode = "UNKNOWN";
}
ESP_LOGD(TAG, "Flash Chip: Size=%ukB Speed=%uMHz Mode=%s",
ESP.getFlashChipSize() / 1024, // NOLINT
ESP.getFlashChipSpeed() / 1000000, flash_mode); // NOLINT
device_info += "|Flash: " + to_string(ESP.getFlashChipSize() / 1024) + // NOLINT
"kB Speed:" + to_string(ESP.getFlashChipSpeed() / 1000000) + "MHz Mode:"; // NOLINT
device_info += flash_mode;
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
ESP_LOGD(TAG, "Flash Chip: Size=%ukB Speed=%uMHz Mode=%s", ESP.getFlashChipSize() / 1024,
ESP.getFlashChipSpeed() / 1000000, flash_mode);
#endif // USE_ARDUINO
#ifdef USE_ESP32
@@ -126,21 +104,10 @@ void DebugComponent::dump_config() {
features += "Other:" + format_hex(info.features);
ESP_LOGD(TAG, "Chip: Model=%s, Features=%s Cores=%u, Revision=%u", model, features.c_str(), info.cores,
info.revision);
device_info += "|Chip: ";
device_info += model;
device_info += " Features:";
device_info += features;
device_info += " Cores:" + to_string(info.cores);
device_info += " Revision:" + to_string(info.revision);
ESP_LOGD(TAG, "ESP-IDF Version: %s", esp_get_idf_version());
device_info += "|ESP-IDF: ";
device_info += esp_get_idf_version();
std::string mac = get_mac_address_pretty();
ESP_LOGD(TAG, "EFuse MAC: %s", mac.c_str());
device_info += "|EFuse MAC: ";
device_info += mac;
ESP_LOGD(TAG, "EFuse MAC: %s", get_mac_address_pretty().c_str());
const char *reset_reason;
switch (rtc_get_reset_reason(0)) {
@@ -193,8 +160,6 @@ void DebugComponent::dump_config() {
reset_reason = "Unknown Reset Reason";
}
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason);
device_info += "|Reset: ";
device_info += reset_reason;
const char *wakeup_reason;
switch (rtc_get_wakeup_cause()) {
@@ -238,8 +203,6 @@ void DebugComponent::dump_config() {
wakeup_reason = "Unknown";
}
ESP_LOGD(TAG, "Wakeup Reason: %s", wakeup_reason);
device_info += "|Wakeup: ";
device_info += wakeup_reason;
#endif
#if defined(USE_ESP8266) && !defined(CLANG_TIDY)
@@ -251,75 +214,20 @@ void DebugComponent::dump_config() {
ESP_LOGD(TAG, "Flash Chip ID=0x%08X", ESP.getFlashChipId());
ESP_LOGD(TAG, "Reset Reason: %s", ESP.getResetReason().c_str());
ESP_LOGD(TAG, "Reset Info: %s", ESP.getResetInfo().c_str());
device_info += "|Chip: 0x" + format_hex(ESP.getChipId());
device_info += "|SDK: ";
device_info += ESP.getSdkVersion();
device_info += "|Core: ";
device_info += ESP.getCoreVersion().c_str();
device_info += "|Boot: ";
device_info += to_string(ESP.getBootVersion());
device_info += "|Mode: " + to_string(ESP.getBootMode());
device_info += "|CPU: " + to_string(ESP.getCpuFreqMHz());
device_info += "|Flash: 0x" + format_hex(ESP.getFlashChipId());
device_info += "|Reset: ";
device_info += ESP.getResetReason().c_str();
device_info += "|";
device_info += ESP.getResetInfo().c_str();
#endif
if (this->device_info_ != nullptr) {
if (device_info.length() > 255)
device_info.resize(255);
this->device_info_->publish_state(device_info);
}
}
void DebugComponent::loop() {
// log when free heap space has halved
uint32_t new_free_heap = get_free_heap();
#ifdef USE_ARDUINO
uint32_t new_free_heap = ESP.getFreeHeap(); // NOLINT(readability-static-accessed-through-instance)
#elif defined(USE_ESP_IDF)
uint32_t new_free_heap = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
#endif
if (new_free_heap < this->free_heap_ / 2) {
this->free_heap_ = new_free_heap;
ESP_LOGD(TAG, "Free Heap Size: %u bytes", this->free_heap_);
this->status_momentary_warning("heap", 1000);
}
// calculate loop time - from last call to this one
if (this->loop_time_sensor_ != nullptr) {
uint32_t now = millis();
uint32_t loop_time = now - this->last_loop_timetag_;
this->max_loop_time_ = std::max(this->max_loop_time_, loop_time);
this->last_loop_timetag_ = now;
}
}
void DebugComponent::update() {
if (this->free_sensor_ != nullptr) {
this->free_sensor_->publish_state(get_free_heap());
}
if (this->block_sensor_ != nullptr) {
#if defined(USE_ESP8266)
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
this->block_sensor_->publish_state(ESP.getMaxFreeBlockSize());
#elif defined(USE_ESP32)
this->block_sensor_->publish_state(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
#endif
}
#if defined(USE_ESP8266) && ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
if (this->fragmentation_sensor_ != nullptr) {
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
this->fragmentation_sensor_->publish_state(ESP.getHeapFragmentation());
}
#endif
if (this->loop_time_sensor_ != nullptr) {
this->loop_time_sensor_->publish_state(this->max_loop_time_);
this->max_loop_time_ = 0;
}
}
float DebugComponent::get_setup_priority() const { return setup_priority::LATE; }
} // namespace debug

View File

@@ -1,42 +1,18 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/macros.h"
#include "esphome/core/helpers.h"
#include "esphome/components/text_sensor/text_sensor.h"
#include "esphome/components/sensor/sensor.h"
namespace esphome {
namespace debug {
class DebugComponent : public PollingComponent {
class DebugComponent : public Component {
public:
void loop() override;
void update() override;
float get_setup_priority() const override;
void dump_config() override;
void set_device_info_sensor(text_sensor::TextSensor *device_info) { device_info_ = device_info; }
void set_free_sensor(sensor::Sensor *free_sensor) { free_sensor_ = free_sensor; }
void set_block_sensor(sensor::Sensor *block_sensor) { block_sensor_ = block_sensor; }
#if defined(USE_ESP8266) && ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
void set_fragmentation_sensor(sensor::Sensor *fragmentation_sensor) { fragmentation_sensor_ = fragmentation_sensor; }
#endif
void set_loop_time_sensor(sensor::Sensor *loop_time_sensor) { loop_time_sensor_ = loop_time_sensor; }
protected:
uint32_t free_heap_{};
uint32_t last_loop_timetag_{0};
uint32_t max_loop_time_{0};
text_sensor::TextSensor *device_info_{nullptr};
sensor::Sensor *free_sensor_{nullptr};
sensor::Sensor *block_sensor_{nullptr};
#if defined(USE_ESP8266) && ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
sensor::Sensor *fragmentation_sensor_{nullptr};
#endif
sensor::Sensor *loop_time_sensor_{nullptr};
};
} // namespace debug

View File

@@ -67,7 +67,7 @@ DemoClimate = demo_ns.class_("DemoClimate", climate.Climate, cg.Component)
DemoClimateType = demo_ns.enum("DemoClimateType", is_class=True)
DemoCover = demo_ns.class_("DemoCover", cover.Cover, cg.Component)
DemoCoverType = demo_ns.enum("DemoCoverType", is_class=True)
DemoFan = demo_ns.class_("DemoFan", fan.Fan, cg.Component)
DemoFan = demo_ns.class_("DemoFan", cg.Component)
DemoFanType = demo_ns.enum("DemoFanType", is_class=True)
DemoLight = demo_ns.class_("DemoLight", light.LightOutput, cg.Component)
DemoLightType = demo_ns.enum("DemoLightType", is_class=True)
@@ -411,7 +411,8 @@ async def to_code(config):
for conf in config[CONF_FANS]:
var = cg.new_Pvariable(conf[CONF_OUTPUT_ID])
await cg.register_component(var, conf)
await fan.register_fan(var, conf)
fan_ = await fan.create_fan_state(conf)
cg.add(var.set_fan(fan_))
cg.add(var.set_type(conf[CONF_TYPE]))
for conf in config[CONF_LIGHTS]:

View File

@@ -1,7 +1,7 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/fan/fan.h"
#include "esphome/components/fan/fan_state.h"
namespace esphome {
namespace demo {
@@ -13,10 +13,11 @@ enum class DemoFanType {
TYPE_4,
};
class DemoFan : public fan::Fan, public Component {
class DemoFan : public Component {
public:
void set_type(DemoFanType type) { type_ = type; }
fan::FanTraits get_traits() override {
void set_fan(fan::FanState *fan) { fan_ = fan; }
void setup() override {
fan::FanTraits traits{};
// oscillation
@@ -42,23 +43,10 @@ class DemoFan : public fan::Fan, public Component {
break;
}
return traits;
}
protected:
void control(const fan::FanCall &call) override {
if (call.get_state().has_value())
this->state = *call.get_state();
if (call.get_oscillating().has_value())
this->oscillating = *call.get_oscillating();
if (call.get_speed().has_value())
this->speed = *call.get_speed();
if (call.get_direction().has_value())
this->direction = *call.get_direction();
this->publish_state();
this->fan_->set_traits(traits);
}
fan::FanState *fan_;
DemoFanType type_;
};

View File

@@ -114,11 +114,10 @@ bool HOT IRAM_ATTR DHT::read_sensor_(float *temperature, float *humidity, bool r
// Wait for rising edge
while (!this->pin_->digital_read()) {
if (micros() - start_time > 90) {
if (i < 0) {
if (i < 0)
error_code = 1;
} else {
else
error_code = 2;
}
break;
}
}
@@ -131,11 +130,10 @@ bool HOT IRAM_ATTR DHT::read_sensor_(float *temperature, float *humidity, bool r
// Wait for falling edge
while (this->pin_->digital_read()) {
if ((end_time = micros()) - start_time > 90) {
if (i < 0) {
if (i < 0)
error_code = 3;
} else {
else
error_code = 4;
}
break;
}
}

View File

@@ -176,10 +176,9 @@ void DisplayBuffer::print(int x, int y, Font *font, Color color, TextAlign align
ESP_LOGW(TAG, "Encountered character without representation in font: '%c'", text[i]);
if (!font->get_glyphs().empty()) {
uint8_t glyph_width = font->get_glyphs()[0].glyph_data_->width;
for (int glyph_x = 0; glyph_x < glyph_width; glyph_x++) {
for (int glyph_x = 0; glyph_x < glyph_width; glyph_x++)
for (int glyph_y = 0; glyph_y < height; glyph_y++)
this->draw_pixel_at(glyph_x + x_at, glyph_y + y_start, color);
}
x_at += glyph_width;
}
@@ -234,14 +233,6 @@ void DisplayBuffer::image(int x, int y, Image *image, Color color_on, Color colo
}
}
break;
case IMAGE_TYPE_TRANSPARENT_BINARY:
for (int img_x = 0; img_x < image->get_width(); img_x++) {
for (int img_y = 0; img_y < image->get_height(); img_y++) {
if (image->get_pixel(img_x, img_y))
this->draw_pixel_at(x + img_x, y + img_y, color_on);
}
}
break;
}
}
@@ -252,12 +243,6 @@ void DisplayBuffer::legend(int x, int y, graph::Graph *graph, Color color_on) {
}
#endif // USE_GRAPH
#ifdef USE_QR_CODE
void DisplayBuffer::qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_on, int scale) {
qr_code->draw(this, x, y, color_on, scale);
}
#endif // USE_QR_CODE
void DisplayBuffer::get_text_bounds(int x, int y, const char *text, Font *font, TextAlign align, int *x1, int *y1,
int *width, int *height) {
int x_offset, baseline;
@@ -432,11 +417,10 @@ int Font::match_next_glyph(const char *str, int *match_length) {
int hi = this->glyphs_.size() - 1;
while (lo != hi) {
int mid = (lo + hi + 1) / 2;
if (this->glyphs_[mid].compare_to(str)) {
if (this->glyphs_[mid].compare_to(str))
lo = mid;
} else {
else
hi = mid - 1;
}
}
*match_length = this->glyphs_[lo].match_length(str);
if (*match_length <= 0)
@@ -462,11 +446,10 @@ void Font::measure(const char *str, int *width, int *x_offset, int *baseline, in
}
const Glyph &glyph = this->glyphs_[glyph_n];
if (!has_char) {
if (!has_char)
min_x = glyph.glyph_data_->offset_x;
} else {
else
min_x = std::min(min_x, x + glyph.glyph_data_->offset_x);
}
x += glyph.glyph_data_->width + glyph.glyph_data_->offset_x;
i += match_length;

View File

@@ -14,10 +14,6 @@
#include "esphome/components/graph/graph.h"
#endif
#ifdef USE_QR_CODE
#include "esphome/components/qr_code/qr_code.h"
#endif
namespace esphome {
namespace display {
@@ -77,12 +73,7 @@ extern const Color COLOR_OFF;
/// Turn the pixel ON.
extern const Color COLOR_ON;
enum ImageType {
IMAGE_TYPE_BINARY = 0,
IMAGE_TYPE_GRAYSCALE = 1,
IMAGE_TYPE_RGB24 = 2,
IMAGE_TYPE_TRANSPARENT_BINARY = 3,
};
enum ImageType { IMAGE_TYPE_BINARY = 0, IMAGE_TYPE_GRAYSCALE = 1, IMAGE_TYPE_RGB24 = 2 };
enum DisplayRotation {
DISPLAY_ROTATION_0_DEGREES = 0,
@@ -311,17 +302,6 @@ class DisplayBuffer {
void legend(int x, int y, graph::Graph *graph, Color color_on = COLOR_ON);
#endif // USE_GRAPH
#ifdef USE_QR_CODE
/** Draw the `qr_code` with the top-left corner at [x,y] to the screen.
*
* @param x The x coordinate of the upper left corner.
* @param y The y coordinate of the upper left corner.
* @param qr_code The qr_code to draw
* @param color_on The color to replace in binary images for the on bits.
*/
void qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_on = COLOR_ON, int scale = 1);
#endif
/** Get the text bounds of the given string.
*
* @param x The x coordinate to place the string at, can be 0 if only interested in dimensions.
@@ -356,15 +336,15 @@ class DisplayBuffer {
// Internal method to set display auto clearing.
void set_auto_clear(bool auto_clear_enabled) { this->auto_clear_enabled_ = auto_clear_enabled; }
virtual int get_height_internal() = 0;
virtual int get_width_internal() = 0;
DisplayRotation get_rotation() const { return this->rotation_; }
protected:
void vprintf_(int x, int y, Font *font, Color color, TextAlign align, const char *format, va_list arg);
virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
virtual int get_height_internal() = 0;
virtual int get_width_internal() = 0;
void init_internal_(uint32_t buffer_length);
void do_update_();

View File

@@ -97,7 +97,7 @@ bool E131Component::process_(int universe, const E131Packet &packet) {
ESP_LOGV(TAG, "Received E1.31 packet for %d universe, with %d bytes", universe, packet.count);
for (auto *light_effect : light_effects_) {
for (auto light_effect : light_effects_) {
handled = light_effect->process_(universe, packet) || handled;
}

View File

@@ -33,9 +33,11 @@ class E131Component : public esphome::Component {
void loop() override;
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
public:
void add_effect(E131AddressableLightEffect *light_effect);
void remove_effect(E131AddressableLightEffect *light_effect);
public:
void set_method(E131ListenMethod listen_method) { this->listen_method_ = listen_method; }
protected:
@@ -45,6 +47,7 @@ class E131Component : public esphome::Component {
void join_(int universe);
void leave_(int universe);
protected:
E131ListenMethod listen_method_{E131_MULTICAST};
std::unique_ptr<UDP> udp_;
std::set<E131AddressableLightEffect *> light_effects_;

View File

@@ -47,7 +47,7 @@ void E131AddressableLightEffect::apply(light::AddressableLight &it, const Color
}
bool E131AddressableLightEffect::process_(int universe, const E131Packet &packet) {
auto *it = get_addressable_();
auto it = get_addressable_();
// check if this is our universe and data are valid
if (universe < first_universe_ || universe > get_last_universe())
@@ -57,7 +57,7 @@ bool E131AddressableLightEffect::process_(int universe, const E131Packet &packet
// limit amount of lights per universe and received
int output_end =
std::min(it->size(), std::min(output_offset + get_lights_per_universe(), output_offset + packet.count - 1));
auto *input_data = packet.values + 1;
auto input_data = packet.values + 1;
ESP_LOGV(TAG, "Applying data for '%s' on %d universe, for %d-%d.", get_name().c_str(), universe, output_offset,
output_end);

View File

@@ -17,16 +17,19 @@ class E131AddressableLightEffect : public light::AddressableLightEffect {
public:
E131AddressableLightEffect(const std::string &name);
public:
void start() override;
void stop() override;
void apply(light::AddressableLight &it, const Color &current_color) override;
public:
int get_data_per_universe() const;
int get_lights_per_universe() const;
int get_first_universe() const;
int get_last_universe() const;
int get_universe_count() const;
public:
void set_first_universe(int universe) { this->first_universe_ = universe; }
void set_channels(E131LightChannels channels) { this->channels_ = channels; }
void set_e131(E131Component *e131) { this->e131_ = e131; }
@@ -34,6 +37,7 @@ class E131AddressableLightEffect : public light::AddressableLightEffect {
protected:
bool process_(int universe, const E131Packet &packet);
protected:
int first_universe_{0};
int last_universe_{0};
E131LightChannels channels_{E131_RGB};

View File

@@ -116,7 +116,7 @@ bool E131Component::packet_(const std::vector<uint8_t> &data, int &universe, E13
if (data.size() < E131_MIN_PACKET_SIZE)
return false;
auto *sbuff = reinterpret_cast<const E131RawPacket *>(&data[0]);
auto sbuff = reinterpret_cast<const E131RawPacket *>(&data[0]);
if (memcmp(sbuff->acn_id, ACN_ID, sizeof(sbuff->acn_id)) != 0)
return false;

View File

@@ -1,166 +0,0 @@
#include "ektf2232.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ektf2232 {
static const char *const TAG = "ektf2232";
static const uint8_t SOFT_RESET_CMD[4] = {0x77, 0x77, 0x77, 0x77};
static const uint8_t HELLO[4] = {0x55, 0x55, 0x55, 0x55};
static const uint8_t GET_X_RES[4] = {0x53, 0x60, 0x00, 0x00};
static const uint8_t GET_Y_RES[4] = {0x53, 0x63, 0x00, 0x00};
static const uint8_t GET_POWER_STATE_CMD[4] = {0x53, 0x50, 0x00, 0x01};
void EKTF2232TouchscreenStore::gpio_intr(EKTF2232TouchscreenStore *store) { store->touch = true; }
void EKTF2232Touchscreen::setup() {
ESP_LOGCONFIG(TAG, "Setting up EKT2232 Touchscreen...");
this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
this->interrupt_pin_->setup();
this->store_.pin = this->interrupt_pin_->to_isr();
this->interrupt_pin_->attach_interrupt(EKTF2232TouchscreenStore::gpio_intr, &this->store_,
gpio::INTERRUPT_FALLING_EDGE);
this->rts_pin_->setup();
this->hard_reset_();
if (!this->soft_reset_()) {
ESP_LOGE(TAG, "Failed to soft reset EKT2232!");
this->interrupt_pin_->detach_interrupt();
this->mark_failed();
return;
}
// Get touch resolution
uint8_t received[4];
this->write(GET_X_RES, 4);
if (this->read(received, 4)) {
ESP_LOGE(TAG, "Failed to read X resolution!");
this->interrupt_pin_->detach_interrupt();
this->mark_failed();
return;
}
this->x_resolution_ = ((received[2])) | ((received[3] & 0xf0) << 4);
this->write(GET_Y_RES, 4);
if (this->read(received, 4)) {
ESP_LOGE(TAG, "Failed to read Y resolution!");
this->interrupt_pin_->detach_interrupt();
this->mark_failed();
return;
}
this->y_resolution_ = ((received[2])) | ((received[3] & 0xf0) << 4);
this->store_.touch = false;
this->set_power_state(true);
}
void EKTF2232Touchscreen::loop() {
if (!this->store_.touch)
return;
this->store_.touch = false;
uint8_t touch_count = 0;
std::vector<TouchPoint> touches;
uint8_t raw[8];
this->read(raw, 8);
for (int i = 0; i < 8; i++) {
if (raw[7] & (1 << i))
touch_count++;
}
if (touch_count == 0) {
for (auto *listener : this->touch_listeners_)
listener->release();
return;
}
touch_count = std::min<uint8_t>(touch_count, 2);
ESP_LOGV(TAG, "Touch count: %d", touch_count);
for (int i = 0; i < touch_count; i++) {
uint8_t *d = raw + 1 + (i * 3);
uint32_t raw_x = (d[0] & 0xF0) << 4 | d[1];
uint32_t raw_y = (d[0] & 0x0F) << 8 | d[2];
raw_x = raw_x * this->display_height_ - 1;
raw_y = raw_y * this->display_width_ - 1;
TouchPoint tp;
switch (this->rotation_) {
case ROTATE_0_DEGREES:
tp.y = raw_x / this->x_resolution_;
tp.x = this->display_width_ - 1 - (raw_y / this->y_resolution_);
break;
case ROTATE_90_DEGREES:
tp.x = raw_x / this->x_resolution_;
tp.y = raw_y / this->y_resolution_;
break;
case ROTATE_180_DEGREES:
tp.y = this->display_height_ - 1 - (raw_x / this->x_resolution_);
tp.x = raw_y / this->y_resolution_;
break;
case ROTATE_270_DEGREES:
tp.x = this->display_height_ - 1 - (raw_x / this->x_resolution_);
tp.y = this->display_width_ - 1 - (raw_y / this->y_resolution_);
break;
}
this->defer([this, tp]() { this->send_touch_(tp); });
}
}
void EKTF2232Touchscreen::set_power_state(bool enable) {
uint8_t data[] = {0x54, 0x50, 0x00, 0x01};
data[1] |= (enable << 3);
this->write(data, 4);
}
bool EKTF2232Touchscreen::get_power_state() {
uint8_t received[4];
this->write(GET_POWER_STATE_CMD, 4);
this->store_.touch = false;
this->read(received, 4);
return (received[1] >> 3) & 1;
}
void EKTF2232Touchscreen::hard_reset_() {
this->rts_pin_->digital_write(false);
delay(15);
this->rts_pin_->digital_write(true);
delay(15);
}
bool EKTF2232Touchscreen::soft_reset_() {
auto err = this->write(SOFT_RESET_CMD, 4);
if (err != i2c::ERROR_OK)
return false;
uint8_t received[4];
uint16_t timeout = 1000;
while (!this->store_.touch && timeout > 0) {
delay(1);
timeout--;
}
if (timeout > 0)
this->store_.touch = true;
this->read(received, 4);
this->store_.touch = false;
return !memcmp(received, HELLO, 4);
}
void EKTF2232Touchscreen::dump_config() {
ESP_LOGCONFIG(TAG, "EKT2232 Touchscreen:");
LOG_I2C_DEVICE(this);
LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
LOG_PIN(" RTS Pin: ", this->rts_pin_);
}
} // namespace ektf2232
} // namespace esphome

View File

@@ -1,45 +0,0 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/touchscreen/touchscreen.h"
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
namespace esphome {
namespace ektf2232 {
struct EKTF2232TouchscreenStore {
volatile bool touch;
ISRInternalGPIOPin pin;
static void gpio_intr(EKTF2232TouchscreenStore *store);
};
using namespace touchscreen;
class EKTF2232Touchscreen : public Touchscreen, public Component, public i2c::I2CDevice {
public:
void setup() override;
void loop() override;
void dump_config() override;
void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
void set_rts_pin(GPIOPin *pin) { this->rts_pin_ = pin; }
void set_power_state(bool enable);
bool get_power_state();
protected:
void hard_reset_();
bool soft_reset_();
InternalGPIOPin *interrupt_pin_;
GPIOPin *rts_pin_;
EKTF2232TouchscreenStore store_;
uint16_t x_resolution_;
uint16_t y_resolution_;
};
} // namespace ektf2232
} // namespace esphome

View File

@@ -1,48 +0,0 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import i2c, touchscreen
from esphome.const import CONF_ID
CODEOWNERS = ["@jesserockz"]
DEPENDENCIES = ["i2c"]
ektf2232_ns = cg.esphome_ns.namespace("ektf2232")
EKTF2232Touchscreen = ektf2232_ns.class_(
"EKTF2232Touchscreen",
touchscreen.Touchscreen,
cg.Component,
i2c.I2CDevice,
)
CONF_EKTF2232_ID = "ektf2232_id"
CONF_INTERRUPT_PIN = "interrupt_pin"
CONF_RTS_PIN = "rts_pin"
CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(EKTF2232Touchscreen),
cv.Required(CONF_INTERRUPT_PIN): cv.All(
pins.internal_gpio_input_pin_schema
),
cv.Required(CONF_RTS_PIN): pins.gpio_output_pin_schema,
}
)
.extend(i2c.i2c_device_schema(0x15))
.extend(cv.COMPONENT_SCHEMA)
)
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)
await touchscreen.register_touchscreen(var, config)
interrupt_pin = await cg.gpio_pin_expression(config[CONF_INTERRUPT_PIN])
cg.add(var.set_interrupt_pin(interrupt_pin))
rts_pin = await cg.gpio_pin_expression(config[CONF_RTS_PIN])
cg.add(var.set_rts_pin(rts_pin))

View File

@@ -18,7 +18,6 @@ from esphome.const import (
KEY_FRAMEWORK_VERSION,
KEY_TARGET_FRAMEWORK,
KEY_TARGET_PLATFORM,
__version__,
)
from esphome.core import CORE, HexInt
import esphome.config_validation as cv
@@ -107,6 +106,7 @@ def _format_framework_espidf_version(ver: cv.Version) -> str:
# The new version needs to be thoroughly validated before changing the
# recommended version as otherwise a bunch of devices could be bricked
# * For all constants below, update platformio.ini (in this repo)
# and platformio.ini/platformio-lint.ini in the esphome-docker-base repository
# The default/recommended arduino framework version
# - https://github.com/espressif/arduino-esp32/releases
@@ -115,16 +115,16 @@ RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(1, 0, 6)
# 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(3, 5, 0)
ARDUINO_PLATFORM_VERSION = cv.Version(3, 3, 2)
# The default/recommended esp-idf framework version
# - https://github.com/espressif/esp-idf/releases
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 3, 2)
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 3, 0)
# The platformio/espressif32 version to use for esp-idf frameworks
# - https://github.com/platformio/platform-espressif32/releases
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
ESP_IDF_PLATFORM_VERSION = cv.Version(3, 5, 0)
ESP_IDF_PLATFORM_VERSION = cv.Version(3, 3, 2)
def _arduino_check_versions(value):
@@ -165,8 +165,8 @@ def _arduino_check_versions(value):
def _esp_idf_check_versions(value):
value = value.copy()
lookups = {
"dev": (cv.Version(5, 0, 0), "https://github.com/espressif/esp-idf.git"),
"latest": (cv.Version(4, 3, 2), None),
"dev": (cv.Version(4, 3, 1), "https://github.com/espressif/esp-idf.git"),
"latest": (cv.Version(4, 3, 0), None),
"recommended": (RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION, None),
}
@@ -293,8 +293,6 @@ async def to_code(config):
cg.add_platformio_option("lib_ldf_mode", "off")
framework_ver: cv.Version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
conf = config[CONF_FRAMEWORK]
cg.add_platformio_option("platform", conf[CONF_PLATFORM_VERSION])
@@ -337,13 +335,6 @@ async def to_code(config):
"CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE", False
)
cg.add_define(
"USE_ESP_IDF_VERSION_CODE",
cg.RawExpression(
f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
),
)
elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
cg.add_platformio_option("framework", "arduino")
cg.add_build_flag("-DUSE_ARDUINO")
@@ -355,13 +346,6 @@ async def to_code(config):
cg.add_platformio_option("board_build.partitions", "partitions.csv")
cg.add_define(
"USE_ARDUINO_VERSION_CODE",
cg.RawExpression(
f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
),
)
ARDUINO_PARTITIONS_CSV = """\
nvs, data, nvs, 0x009000, 0x005000,
@@ -431,17 +415,9 @@ def copy_files():
CORE.relative_build_path("partitions.csv"),
IDF_PARTITIONS_CSV,
)
# IDF build scripts look for version string to put in the build.
# However, if the build path does not have an initialized git repo,
# and no version.txt file exists, the CMake script fails for some setups.
# Fix by manually pasting a version.txt file, containing the ESPHome version
write_file_if_changed(
CORE.relative_build_path("version.txt"),
__version__,
)
dir = os.path.dirname(__file__)
post_build_file = os.path.join(dir, "post_build.py.script")
post_build_file = os.path.join(dir, "post_build.py")
copy_file_if_changed(
post_build_file,
CORE.relative_build_path("post_build.py"),

View File

@@ -147,46 +147,40 @@ bool BLECharacteristic::is_failed() {
}
void BLECharacteristic::set_broadcast_property(bool value) {
if (value) {
if (value)
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ | ESP_GATT_CHAR_PROP_BIT_BROADCAST);
} else {
else
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_BROADCAST);
}
}
void BLECharacteristic::set_indicate_property(bool value) {
if (value) {
if (value)
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ | ESP_GATT_CHAR_PROP_BIT_INDICATE);
} else {
else
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_INDICATE);
}
}
void BLECharacteristic::set_notify_property(bool value) {
if (value) {
if (value)
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
} else {
else
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_NOTIFY);
}
}
void BLECharacteristic::set_read_property(bool value) {
if (value) {
if (value)
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ | ESP_GATT_CHAR_PROP_BIT_READ);
} else {
else
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_READ);
}
}
void BLECharacteristic::set_write_property(bool value) {
if (value) {
if (value)
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ | ESP_GATT_CHAR_PROP_BIT_WRITE);
} else {
else
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_WRITE);
}
}
void BLECharacteristic::set_write_no_response_property(bool value) {
if (value) {
if (value)
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ | ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
} else {
else
this->properties_ = (esp_gatt_char_prop_t)(this->properties_ & ~ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
}
}
void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,

View File

@@ -18,10 +18,9 @@ BLEService::~BLEService() {
}
BLECharacteristic *BLEService::get_characteristic(ESPBTUUID uuid) {
for (auto *chr : this->characteristics_) {
for (auto *chr : this->characteristics_)
if (chr->get_uuid() == uuid)
return chr;
}
return nullptr;
}

View File

@@ -58,12 +58,11 @@ void ESP32BLETracker::setup() {
void ESP32BLETracker::loop() {
BLEEvent *ble_event = this->ble_events_.pop();
while (ble_event != nullptr) {
if (ble_event->type_) {
if (ble_event->type_)
this->real_gattc_event_handler_(ble_event->event_.gattc.gattc_event, ble_event->event_.gattc.gattc_if,
&ble_event->event_.gattc.gattc_param);
} else {
else
this->real_gap_event_handler_(ble_event->event_.gap.gap_event, &ble_event->event_.gap.gap_param);
}
delete ble_event; // NOLINT(cppcoreguidelines-owning-memory)
ble_event = this->ble_events_.pop();
}
@@ -90,12 +89,11 @@ void ESP32BLETracker::loop() {
device.parse_scan_rst(this->scan_result_buffer_[i]);
bool found = false;
for (auto *listener : this->listeners_) {
for (auto *listener : this->listeners_)
if (listener->parse_device(device))
found = true;
}
for (auto *client : this->clients_) {
for (auto *client : this->clients_)
if (client->parse_device(device)) {
found = true;
if (client->state() == ClientState::DISCOVERED) {
@@ -105,7 +103,6 @@ void ESP32BLETracker::loop() {
}
}
}
}
if (!found) {
this->print_bt_device_info(device);

View File

@@ -23,7 +23,6 @@ AUTO_LOAD = ["psram"]
esp32_camera_ns = cg.esphome_ns.namespace("esp32_camera")
ESP32Camera = esp32_camera_ns.class_("ESP32Camera", cg.PollingComponent, cg.EntityBase)
ESP32CameraFrameSize = esp32_camera_ns.enum("ESP32CameraFrameSize")
FRAME_SIZES = {
"160X120": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
@@ -47,76 +46,30 @@ FRAME_SIZES = {
"1600X1200": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
"UXGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
}
ESP32GainControlMode = esp32_camera_ns.enum("ESP32GainControlMode")
ENUM_GAIN_CONTROL_MODE = {
"MANUAL": ESP32GainControlMode.ESP32_GC_MODE_MANU,
"AUTO": ESP32GainControlMode.ESP32_GC_MODE_AUTO,
}
ESP32AgcGainCeiling = esp32_camera_ns.enum("ESP32AgcGainCeiling")
ENUM_GAIN_CEILING = {
"2X": ESP32AgcGainCeiling.ESP32_GAINCEILING_2X,
"4X": ESP32AgcGainCeiling.ESP32_GAINCEILING_4X,
"8X": ESP32AgcGainCeiling.ESP32_GAINCEILING_8X,
"16X": ESP32AgcGainCeiling.ESP32_GAINCEILING_16X,
"32X": ESP32AgcGainCeiling.ESP32_GAINCEILING_32X,
"64X": ESP32AgcGainCeiling.ESP32_GAINCEILING_64X,
"128X": ESP32AgcGainCeiling.ESP32_GAINCEILING_128X,
}
ESP32WhiteBalanceMode = esp32_camera_ns.enum("ESP32WhiteBalanceMode")
ENUM_WB_MODE = {
"AUTO": ESP32WhiteBalanceMode.ESP32_WB_MODE_AUTO,
"SUNNY": ESP32WhiteBalanceMode.ESP32_WB_MODE_SUNNY,
"CLOUDY": ESP32WhiteBalanceMode.ESP32_WB_MODE_CLOUDY,
"OFFICE": ESP32WhiteBalanceMode.ESP32_WB_MODE_OFFICE,
"HOME": ESP32WhiteBalanceMode.ESP32_WB_MODE_HOME,
}
ESP32SpecialEffect = esp32_camera_ns.enum("ESP32SpecialEffect")
ENUM_SPECIAL_EFFECT = {
"NONE": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_NONE,
"NEGATIVE": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_NEGATIVE,
"GRAYSCALE": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_GRAYSCALE,
"RED_TINT": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_RED_TINT,
"GREEN_TINT": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_GREEN_TINT,
"BLUE_TINT": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_BLUE_TINT,
"SEPIA": ESP32SpecialEffect.ESP32_SPECIAL_EFFECT_SEPIA,
}
# pin assignment
CONF_VSYNC_PIN = "vsync_pin"
CONF_HREF_PIN = "href_pin"
CONF_PIXEL_CLOCK_PIN = "pixel_clock_pin"
CONF_EXTERNAL_CLOCK = "external_clock"
CONF_I2C_PINS = "i2c_pins"
CONF_POWER_DOWN_PIN = "power_down_pin"
# image
CONF_MAX_FRAMERATE = "max_framerate"
CONF_IDLE_FRAMERATE = "idle_framerate"
CONF_JPEG_QUALITY = "jpeg_quality"
CONF_VERTICAL_FLIP = "vertical_flip"
CONF_HORIZONTAL_MIRROR = "horizontal_mirror"
CONF_SATURATION = "saturation"
CONF_SPECIAL_EFFECT = "special_effect"
# exposure
CONF_AEC_MODE = "aec_mode"
CONF_AEC2 = "aec2"
CONF_AE_LEVEL = "ae_level"
CONF_AEC_VALUE = "aec_value"
# gains
CONF_AGC_MODE = "agc_mode"
CONF_AGC_VALUE = "agc_value"
CONF_AGC_GAIN_CEILING = "agc_gain_ceiling"
# white balance
CONF_WB_MODE = "wb_mode"
# test pattern
CONF_SATURATION = "saturation"
CONF_TEST_PATTERN = "test_pattern"
# framerates
CONF_MAX_FRAMERATE = "max_framerate"
CONF_IDLE_FRAMERATE = "idle_framerate"
camera_range_param = cv.int_range(min=-2, max=2)
CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(ESP32Camera),
# pin assignment
cv.Required(CONF_DATA_PINS): cv.All(
[pins.internal_gpio_input_pin_number], cv.Length(min=8, max=8)
),
@@ -139,7 +92,12 @@ CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
),
cv.Optional(CONF_RESET_PIN): pins.internal_gpio_output_pin_number,
cv.Optional(CONF_POWER_DOWN_PIN): pins.internal_gpio_output_pin_number,
# image
cv.Optional(CONF_MAX_FRAMERATE, default="10 fps"): cv.All(
cv.framerate, cv.Range(min=0, min_included=False, max=60)
),
cv.Optional(CONF_IDLE_FRAMERATE, default="0.1 fps"): cv.All(
cv.framerate, cv.Range(min=0, max=1)
),
cv.Optional(CONF_RESOLUTION, default="640X480"): cv.enum(
FRAME_SIZES, upper=True
),
@@ -149,66 +107,29 @@ CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
cv.Optional(CONF_SATURATION, default=0): camera_range_param,
cv.Optional(CONF_VERTICAL_FLIP, default=True): cv.boolean,
cv.Optional(CONF_HORIZONTAL_MIRROR, default=True): cv.boolean,
cv.Optional(CONF_SPECIAL_EFFECT, default="NONE"): cv.enum(
ENUM_SPECIAL_EFFECT, upper=True
),
# exposure
cv.Optional(CONF_AGC_MODE, default="AUTO"): cv.enum(
ENUM_GAIN_CONTROL_MODE, upper=True
),
cv.Optional(CONF_AEC2, default=False): cv.boolean,
cv.Optional(CONF_AE_LEVEL, default=0): camera_range_param,
cv.Optional(CONF_AEC_VALUE, default=300): cv.int_range(min=0, max=1200),
# gains
cv.Optional(CONF_AEC_MODE, default="AUTO"): cv.enum(
ENUM_GAIN_CONTROL_MODE, upper=True
),
cv.Optional(CONF_AGC_VALUE, default=0): cv.int_range(min=0, max=30),
cv.Optional(CONF_AGC_GAIN_CEILING, default="2X"): cv.enum(
ENUM_GAIN_CEILING, upper=True
),
# white balance
cv.Optional(CONF_WB_MODE, default="AUTO"): cv.enum(ENUM_WB_MODE, upper=True),
# test pattern
cv.Optional(CONF_TEST_PATTERN, default=False): cv.boolean,
# framerates
cv.Optional(CONF_MAX_FRAMERATE, default="10 fps"): cv.All(
cv.framerate, cv.Range(min=0, min_included=False, max=60)
),
cv.Optional(CONF_IDLE_FRAMERATE, default="0.1 fps"): cv.All(
cv.framerate, cv.Range(min=0, max=1)
),
}
).extend(cv.COMPONENT_SCHEMA)
SETTERS = {
# pin assignment
CONF_DATA_PINS: "set_data_pins",
CONF_VSYNC_PIN: "set_vsync_pin",
CONF_HREF_PIN: "set_href_pin",
CONF_PIXEL_CLOCK_PIN: "set_pixel_clock_pin",
CONF_RESET_PIN: "set_reset_pin",
CONF_POWER_DOWN_PIN: "set_power_down_pin",
# image
CONF_JPEG_QUALITY: "set_jpeg_quality",
CONF_VERTICAL_FLIP: "set_vertical_flip",
CONF_HORIZONTAL_MIRROR: "set_horizontal_mirror",
CONF_CONTRAST: "set_contrast",
CONF_BRIGHTNESS: "set_brightness",
CONF_SATURATION: "set_saturation",
CONF_SPECIAL_EFFECT: "set_special_effect",
# exposure
CONF_AEC_MODE: "set_aec_mode",
CONF_AEC2: "set_aec2",
CONF_AE_LEVEL: "set_ae_level",
CONF_AEC_VALUE: "set_aec_value",
# gains
CONF_AGC_MODE: "set_agc_mode",
CONF_AGC_VALUE: "set_agc_value",
CONF_AGC_GAIN_CEILING: "set_agc_gain_ceiling",
# white balance
CONF_WB_MODE: "set_wb_mode",
# test pattern
CONF_CONTRAST: "set_contrast",
CONF_BRIGHTNESS: "set_brightness",
CONF_SATURATION: "set_saturation",
CONF_TEST_PATTERN: "set_test_pattern",
}

View File

@@ -11,14 +11,10 @@ namespace esp32_camera {
static const char *const TAG = "esp32_camera";
/* ---------------- public API (derivated) ---------------- */
void ESP32Camera::setup() {
global_esp32_camera = this;
/* initialize time to now */
this->last_update_ = millis();
/* initialize camera */
esp_err_t err = esp_camera_init(&this->config_);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_camera_init failed: %s", esp_err_to_name(err));
@@ -27,10 +23,16 @@ void ESP32Camera::setup() {
return;
}
/* initialize camera parameters */
this->update_camera_parameters();
/* initialize RTOS */
sensor_t *s = esp_camera_sensor_get();
s->set_vflip(s, this->vertical_flip_);
s->set_hmirror(s, this->horizontal_mirror_);
s->set_aec2(s, this->aec2_); // 0 = disable , 1 = enable
s->set_ae_level(s, this->ae_level_); // -2 to 2
s->set_aec_value(s, this->aec_value_); // 0 to 1200
s->set_contrast(s, this->contrast_);
s->set_brightness(s, this->brightness_);
s->set_saturation(s, this->saturation_);
s->set_colorbar(s, this->test_pattern_);
this->framebuffer_get_queue_ = xQueueCreate(1, sizeof(camera_fb_t *));
this->framebuffer_return_queue_ = xQueueCreate(1, sizeof(camera_fb_t *));
xTaskCreatePinnedToCore(&ESP32Camera::framebuffer_task,
@@ -42,7 +44,6 @@ void ESP32Camera::setup() {
1 // core
);
}
void ESP32Camera::dump_config() {
auto conf = this->config_;
ESP_LOGCONFIG(TAG, "ESP32 Camera:");
@@ -105,17 +106,17 @@ void ESP32Camera::dump_config() {
ESP_LOGCONFIG(TAG, " Saturation: %d", st.saturation);
ESP_LOGCONFIG(TAG, " Vertical Flip: %s", ONOFF(st.vflip));
ESP_LOGCONFIG(TAG, " Horizontal Mirror: %s", ONOFF(st.hmirror));
ESP_LOGCONFIG(TAG, " Special Effect: %u", st.special_effect);
ESP_LOGCONFIG(TAG, " White Balance Mode: %u", st.wb_mode);
// ESP_LOGCONFIG(TAG, " Special Effect: %u", st.special_effect);
// ESP_LOGCONFIG(TAG, " White Balance Mode: %u", st.wb_mode);
// ESP_LOGCONFIG(TAG, " Auto White Balance: %u", st.awb);
// ESP_LOGCONFIG(TAG, " Auto White Balance Gain: %u", st.awb_gain);
ESP_LOGCONFIG(TAG, " Auto Exposure Control: %u", st.aec);
// ESP_LOGCONFIG(TAG, " Auto Exposure Control: %u", st.aec);
ESP_LOGCONFIG(TAG, " Auto Exposure Control 2: %u", st.aec2);
ESP_LOGCONFIG(TAG, " Auto Exposure Level: %d", st.ae_level);
ESP_LOGCONFIG(TAG, " Auto Exposure Value: %u", st.aec_value);
ESP_LOGCONFIG(TAG, " AGC: %u", st.agc);
ESP_LOGCONFIG(TAG, " AGC Gain: %u", st.agc_gain);
ESP_LOGCONFIG(TAG, " Gain Ceiling: %u", st.gainceiling);
// ESP_LOGCONFIG(TAG, " AGC: %u", st.agc);
// ESP_LOGCONFIG(TAG, " AGC Gain: %u", st.agc_gain);
// ESP_LOGCONFIG(TAG, " Gain Ceiling: %u", st.gainceiling);
// ESP_LOGCONFIG(TAG, " BPC: %u", st.bpc);
// ESP_LOGCONFIG(TAG, " WPC: %u", st.wpc);
// ESP_LOGCONFIG(TAG, " RAW_GMA: %u", st.raw_gma);
@@ -123,7 +124,6 @@ void ESP32Camera::dump_config() {
// ESP_LOGCONFIG(TAG, " DCW: %u", st.dcw);
ESP_LOGCONFIG(TAG, " Test Pattern: %s", YESNO(st.colorbar));
}
void ESP32Camera::loop() {
// check if we can return the image
if (this->can_return_image_()) {
@@ -170,10 +170,15 @@ void ESP32Camera::loop() {
this->last_update_ = now;
this->single_requesters_ = 0;
}
float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }
/* ---------------- constructors ---------------- */
void ESP32Camera::framebuffer_task(void *pv) {
while (true) {
camera_fb_t *framebuffer = esp_camera_fb_get();
xQueueSend(global_esp32_camera->framebuffer_get_queue_, &framebuffer, portMAX_DELAY);
// return is no-op for config with 1 fb
xQueueReceive(global_esp32_camera->framebuffer_return_queue_, &framebuffer, portMAX_DELAY);
esp_camera_fb_return(framebuffer);
}
}
ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
this->config_.pin_pwdn = -1;
this->config_.pin_reset = -1;
@@ -188,9 +193,6 @@ ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
global_esp32_camera = this;
}
ESP32Camera::ESP32Camera() : ESP32Camera("") {}
/* ---------------- setters ---------------- */
/* set pin assignment */
void ESP32Camera::set_data_pins(std::array<uint8_t, 8> pins) {
this->config_.pin_d0 = pins[0];
this->config_.pin_d1 = pins[1];
@@ -212,10 +214,6 @@ void ESP32Camera::set_i2c_pins(uint8_t sda, uint8_t scl) {
this->config_.pin_sscb_sda = sda;
this->config_.pin_sscb_scl = scl;
}
void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }
/* set image parameters */
void ESP32Camera::set_frame_size(ESP32CameraFrameSize size) {
switch (size) {
case ESP32_CAMERA_SIZE_160X120:
@@ -251,81 +249,36 @@ void ESP32Camera::set_frame_size(ESP32CameraFrameSize size) {
}
}
void ESP32Camera::set_jpeg_quality(uint8_t quality) { this->config_.jpeg_quality = quality; }
void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }
void ESP32Camera::add_image_callback(std::function<void(std::shared_ptr<CameraImage>)> &&f) {
this->new_image_callback_.add(std::move(f));
}
void ESP32Camera::set_vertical_flip(bool vertical_flip) { this->vertical_flip_ = vertical_flip; }
void ESP32Camera::set_horizontal_mirror(bool horizontal_mirror) { this->horizontal_mirror_ = horizontal_mirror; }
void ESP32Camera::set_contrast(int contrast) { this->contrast_ = contrast; }
void ESP32Camera::set_brightness(int brightness) { this->brightness_ = brightness; }
void ESP32Camera::set_saturation(int saturation) { this->saturation_ = saturation; }
void ESP32Camera::set_special_effect(ESP32SpecialEffect effect) { this->special_effect_ = effect; }
/* set exposure parameters */
void ESP32Camera::set_aec_mode(ESP32GainControlMode mode) { this->aec_mode_ = mode; }
void ESP32Camera::set_aec2(bool aec2) { this->aec2_ = aec2; }
void ESP32Camera::set_ae_level(int ae_level) { this->ae_level_ = ae_level; }
void ESP32Camera::set_aec_value(uint32_t aec_value) { this->aec_value_ = aec_value; }
/* set gains parameters */
void ESP32Camera::set_agc_mode(ESP32GainControlMode mode) { this->agc_mode_ = mode; }
void ESP32Camera::set_agc_value(uint8_t agc_value) { this->agc_value_ = agc_value; }
void ESP32Camera::set_agc_gain_ceiling(ESP32AgcGainCeiling gain_ceiling) { this->agc_gain_ceiling_ = gain_ceiling; }
/* set white balance */
void ESP32Camera::set_wb_mode(ESP32WhiteBalanceMode mode) { this->wb_mode_ = mode; }
/* set test mode */
void ESP32Camera::set_test_pattern(bool test_pattern) { this->test_pattern_ = test_pattern; }
/* set fps */
void ESP32Camera::set_contrast(int contrast) { this->contrast_ = contrast; }
void ESP32Camera::set_brightness(int brightness) { this->brightness_ = brightness; }
void ESP32Camera::set_saturation(int saturation) { this->saturation_ = saturation; }
float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }
uint32_t ESP32Camera::hash_base() { return 3010542557UL; }
void ESP32Camera::request_image(CameraRequester requester) { this->single_requesters_ |= 1 << requester; }
void ESP32Camera::start_stream(CameraRequester requester) { this->stream_requesters_ |= 1 << requester; }
void ESP32Camera::stop_stream(CameraRequester requester) { this->stream_requesters_ &= ~(1 << requester); }
bool ESP32Camera::has_requested_image_() const { return this->single_requesters_ || this->stream_requesters_; }
bool ESP32Camera::can_return_image_() const { return this->current_image_.use_count() == 1; }
void ESP32Camera::set_max_update_interval(uint32_t max_update_interval) {
this->max_update_interval_ = max_update_interval;
}
void ESP32Camera::set_idle_update_interval(uint32_t idle_update_interval) {
this->idle_update_interval_ = idle_update_interval;
}
/* ---------------- public API (specific) ---------------- */
void ESP32Camera::add_image_callback(std::function<void(std::shared_ptr<CameraImage>)> &&f) {
this->new_image_callback_.add(std::move(f));
}
void ESP32Camera::start_stream(CameraRequester requester) { this->stream_requesters_ |= (1U << requester); }
void ESP32Camera::stop_stream(CameraRequester requester) { this->stream_requesters_ &= ~(1U << requester); }
void ESP32Camera::request_image(CameraRequester requester) { this->single_requesters_ |= (1U << requester); }
void ESP32Camera::update_camera_parameters() {
sensor_t *s = esp_camera_sensor_get();
/* update image */
s->set_vflip(s, this->vertical_flip_);
s->set_hmirror(s, this->horizontal_mirror_);
s->set_contrast(s, this->contrast_);
s->set_brightness(s, this->brightness_);
s->set_saturation(s, this->saturation_);
s->set_special_effect(s, (int) this->special_effect_); // 0 to 6
/* update exposure */
s->set_exposure_ctrl(s, (bool) this->aec_mode_);
s->set_aec2(s, this->aec2_); // 0 = disable , 1 = enable
s->set_ae_level(s, this->ae_level_); // -2 to 2
s->set_aec_value(s, this->aec_value_); // 0 to 1200
/* update gains */
s->set_gain_ctrl(s, (bool) this->agc_mode_);
s->set_agc_gain(s, (int) this->agc_value_); // 0 to 30
s->set_gainceiling(s, (gainceiling_t) this->agc_gain_ceiling_);
/* update white balance mode */
s->set_wb_mode(s, (int) this->wb_mode_); // 0 to 4
/* update test patern */
s->set_colorbar(s, this->test_pattern_);
}
/* ---------------- Internal methods ---------------- */
uint32_t ESP32Camera::hash_base() { return 3010542557UL; }
bool ESP32Camera::has_requested_image_() const { return this->single_requesters_ || this->stream_requesters_; }
bool ESP32Camera::can_return_image_() const { return this->current_image_.use_count() == 1; }
void ESP32Camera::framebuffer_task(void *pv) {
while (true) {
camera_fb_t *framebuffer = esp_camera_fb_get();
xQueueSend(global_esp32_camera->framebuffer_get_queue_, &framebuffer, portMAX_DELAY);
// return is no-op for config with 1 fb
xQueueReceive(global_esp32_camera->framebuffer_return_queue_, &framebuffer, portMAX_DELAY);
esp_camera_fb_return(framebuffer);
}
}
void ESP32Camera::set_test_pattern(bool test_pattern) { this->test_pattern_ = test_pattern; }
ESP32Camera *global_esp32_camera; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
/* ---------------- CameraImageReader class ---------------- */
void CameraImageReader::set_image(std::shared_ptr<CameraImage> image) {
this->image_ = std::move(image);
this->offset_ = 0;
@@ -340,15 +293,13 @@ void CameraImageReader::return_image() { this->image_.reset(); }
void CameraImageReader::consume_data(size_t consumed) { this->offset_ += consumed; }
uint8_t *CameraImageReader::peek_data_buffer() { return this->image_->get_data_buffer() + this->offset_; }
/* ---------------- CameraImage class ---------------- */
CameraImage::CameraImage(camera_fb_t *buffer, uint8_t requesters) : buffer_(buffer), requesters_(requesters) {}
camera_fb_t *CameraImage::get_raw_buffer() { return this->buffer_; }
uint8_t *CameraImage::get_data_buffer() { return this->buffer_->buf; }
size_t CameraImage::get_data_length() { return this->buffer_->len; }
bool CameraImage::was_requested_by(CameraRequester requester) const {
return (this->requesters_ & (1 << requester)) != 0;
}
CameraImage::CameraImage(camera_fb_t *buffer, uint8_t requesters) : buffer_(buffer), requesters_(requesters) {}
} // namespace esp32_camera
} // namespace esphome

View File

@@ -14,9 +14,34 @@ namespace esp32_camera {
class ESP32Camera;
/* ---------------- enum classes ---------------- */
enum CameraRequester { IDLE, API_REQUESTER, WEB_REQUESTER };
class CameraImage {
public:
CameraImage(camera_fb_t *buffer, uint8_t requester);
camera_fb_t *get_raw_buffer();
uint8_t *get_data_buffer();
size_t get_data_length();
bool was_requested_by(CameraRequester requester) const;
protected:
camera_fb_t *buffer_;
uint8_t requesters_;
};
class CameraImageReader {
public:
void set_image(std::shared_ptr<CameraImage> image);
size_t available() const;
uint8_t *peek_data_buffer();
void consume_data(size_t consumed);
void return_image();
protected:
std::shared_ptr<CameraImage> image_;
size_t offset_{0};
};
enum ESP32CameraFrameSize {
ESP32_CAMERA_SIZE_160X120, // QQVGA
ESP32_CAMERA_SIZE_176X144, // QCIF
@@ -30,155 +55,57 @@ enum ESP32CameraFrameSize {
ESP32_CAMERA_SIZE_1600X1200, // UXGA
};
enum ESP32AgcGainCeiling {
ESP32_GAINCEILING_2X = GAINCEILING_2X,
ESP32_GAINCEILING_4X = GAINCEILING_4X,
ESP32_GAINCEILING_8X = GAINCEILING_8X,
ESP32_GAINCEILING_16X = GAINCEILING_16X,
ESP32_GAINCEILING_32X = GAINCEILING_32X,
ESP32_GAINCEILING_64X = GAINCEILING_64X,
ESP32_GAINCEILING_128X = GAINCEILING_128X,
};
enum ESP32GainControlMode {
ESP32_GC_MODE_MANU = false,
ESP32_GC_MODE_AUTO = true,
};
enum ESP32WhiteBalanceMode {
ESP32_WB_MODE_AUTO = 0U,
ESP32_WB_MODE_SUNNY = 1U,
ESP32_WB_MODE_CLOUDY = 2U,
ESP32_WB_MODE_OFFICE = 3U,
ESP32_WB_MODE_HOME = 4U,
};
enum ESP32SpecialEffect {
ESP32_SPECIAL_EFFECT_NONE = 0U,
ESP32_SPECIAL_EFFECT_NEGATIVE = 1U,
ESP32_SPECIAL_EFFECT_GRAYSCALE = 2U,
ESP32_SPECIAL_EFFECT_RED_TINT = 3U,
ESP32_SPECIAL_EFFECT_GREEN_TINT = 4U,
ESP32_SPECIAL_EFFECT_BLUE_TINT = 5U,
ESP32_SPECIAL_EFFECT_SEPIA = 6U,
};
/* ---------------- CameraImage class ---------------- */
class CameraImage {
public:
CameraImage(camera_fb_t *buffer, uint8_t requester);
camera_fb_t *get_raw_buffer();
uint8_t *get_data_buffer();
size_t get_data_length();
bool was_requested_by(CameraRequester requester) const;
protected:
camera_fb_t *buffer_;
uint8_t requesters_;
};
/* ---------------- CameraImageReader class ---------------- */
class CameraImageReader {
public:
void set_image(std::shared_ptr<CameraImage> image);
size_t available() const;
uint8_t *peek_data_buffer();
void consume_data(size_t consumed);
void return_image();
protected:
std::shared_ptr<CameraImage> image_;
size_t offset_{0};
};
/* ---------------- ESP32Camera class ---------------- */
class ESP32Camera : public Component, public EntityBase {
public:
ESP32Camera(const std::string &name);
ESP32Camera();
/* setters */
/* -- pin assignment */
void set_data_pins(std::array<uint8_t, 8> pins);
void set_vsync_pin(uint8_t pin);
void set_href_pin(uint8_t pin);
void set_pixel_clock_pin(uint8_t pin);
void set_external_clock(uint8_t pin, uint32_t frequency);
void set_i2c_pins(uint8_t sda, uint8_t scl);
void set_reset_pin(uint8_t pin);
void set_power_down_pin(uint8_t pin);
/* -- image */
void set_frame_size(ESP32CameraFrameSize size);
void set_jpeg_quality(uint8_t quality);
void set_reset_pin(uint8_t pin);
void set_power_down_pin(uint8_t pin);
void set_vertical_flip(bool vertical_flip);
void set_horizontal_mirror(bool horizontal_mirror);
void set_contrast(int contrast);
void set_brightness(int brightness);
void set_saturation(int saturation);
void set_special_effect(ESP32SpecialEffect effect);
/* -- exposure */
void set_aec_mode(ESP32GainControlMode mode);
void set_aec2(bool aec2);
void set_ae_level(int ae_level);
void set_aec_value(uint32_t aec_value);
/* -- gains */
void set_agc_mode(ESP32GainControlMode mode);
void set_agc_value(uint8_t agc_value);
void set_agc_gain_ceiling(ESP32AgcGainCeiling gain_ceiling);
/* -- white balance */
void set_wb_mode(ESP32WhiteBalanceMode mode);
/* -- test */
void set_test_pattern(bool test_pattern);
/* -- framerates */
void set_contrast(int contrast);
void set_brightness(int brightness);
void set_saturation(int saturation);
void set_max_update_interval(uint32_t max_update_interval);
void set_idle_update_interval(uint32_t idle_update_interval);
/* public API (derivated) */
void set_test_pattern(bool test_pattern);
void setup() override;
void loop() override;
void dump_config() override;
float get_setup_priority() const override;
/* public API (specific) */
void add_image_callback(std::function<void(std::shared_ptr<CameraImage>)> &&f);
float get_setup_priority() const override;
void start_stream(CameraRequester requester);
void stop_stream(CameraRequester requester);
void request_image(CameraRequester requester);
void update_camera_parameters();
protected:
/* internal methods */
uint32_t hash_base() override;
bool has_requested_image_() const;
bool can_return_image_() const;
static void framebuffer_task(void *pv);
/* attributes */
/* camera configuration */
camera_config_t config_{};
/* -- image */
bool vertical_flip_{true};
bool horizontal_mirror_{true};
int contrast_{0};
int brightness_{0};
int saturation_{0};
ESP32SpecialEffect special_effect_{ESP32_SPECIAL_EFFECT_NONE};
/* -- exposure */
ESP32GainControlMode aec_mode_{ESP32_GC_MODE_AUTO};
bool aec2_{false};
int ae_level_{0};
uint32_t aec_value_{300};
/* -- gains */
ESP32GainControlMode agc_mode_{ESP32_GC_MODE_AUTO};
uint8_t agc_value_{0};
ESP32AgcGainCeiling agc_gain_ceiling_{ESP32_GAINCEILING_2X};
/* -- white balance */
ESP32WhiteBalanceMode wb_mode_{ESP32_WB_MODE_AUTO};
/* -- Test */
int contrast_{0};
int brightness_{0};
int saturation_{0};
bool test_pattern_{false};
/* -- framerates */
uint32_t max_update_interval_{1000};
uint32_t idle_update_interval_{15000};
esp_err_t init_error_{ESP_OK};
std::shared_ptr<CameraImage> current_image_;
@@ -187,7 +114,8 @@ class ESP32Camera : public Component, public EntityBase {
QueueHandle_t framebuffer_get_queue_;
QueueHandle_t framebuffer_return_queue_;
CallbackManager<void(std::shared_ptr<CameraImage>)> new_image_callback_;
uint32_t max_update_interval_{1000};
uint32_t idle_update_interval_{15000};
uint32_t last_idle_request_{0};
uint32_t last_update_{0};
};

View File

@@ -87,11 +87,10 @@ void CameraWebServer::on_shutdown() {
void CameraWebServer::dump_config() {
ESP_LOGCONFIG(TAG, "ESP32 Camera Web Server:");
ESP_LOGCONFIG(TAG, " Port: %d", this->port_);
if (this->mode_ == STREAM) {
if (this->mode_ == STREAM)
ESP_LOGCONFIG(TAG, " Mode: stream");
} else {
else
ESP_LOGCONFIG(TAG, " Mode: snapshot");
}
if (this->is_failed()) {
ESP_LOGE(TAG, " Setup Failed");

View File

@@ -36,6 +36,7 @@ class CameraWebServer : public Component {
esp_err_t streaming_handler_(struct httpd_req *req);
esp_err_t snapshot_handler_(struct httpd_req *req);
protected:
uint16_t port_{0};
void *httpd_{nullptr};
SemaphoreHandle_t semaphore_;

View File

@@ -56,7 +56,7 @@ async def to_code(config):
cg.add(ble_server.register_service_component(var))
cg.add_define("USE_IMPROV")
cg.add_library("esphome/Improv", "1.2.0")
cg.add_library("esphome/Improv", "1.0.0")
cg.add(var.set_identify_duration(config[CONF_IDENTIFY_DURATION]))
cg.add(var.set_authorized_duration(config[CONF_AUTHORIZED_DURATION]))

View File

@@ -128,7 +128,7 @@ void ESP32ImprovComponent::loop() {
std::vector<std::string> urls = {ESPHOME_MY_LINK};
#ifdef USE_WEBSERVER
auto ip = wifi::global_wifi_component->wifi_sta_ip();
std::string webserver_url = "http://" + ip.str() + ":" + to_string(USE_WEBSERVER_PORT);
std::string webserver_url = "http://" + ip.str() + ":" + to_string(WEBSERVER_PORT);
urls.push_back(webserver_url);
#endif
std::vector<uint8_t> data = improv::build_rpc_response(improv::WIFI_SETTINGS, urls);

View File

@@ -162,7 +162,7 @@ void ESP32TouchComponent::on_shutdown() {
}
ESP32TouchBinarySensor::ESP32TouchBinarySensor(touch_pad_t touch_pad, uint16_t threshold, uint16_t wakeup_threshold)
: touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {}
: BinarySensor(), touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {}
} // namespace esp32_touch
} // namespace esphome

View File

@@ -61,7 +61,7 @@ def _format_framework_arduino_version(ver: cv.Version) -> str:
# The default/recommended arduino framework version
# - https://github.com/esp8266/Arduino/releases
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif8266
RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 0, 2)
RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(2, 7, 4)
# The platformio/espressif8266 version to use for arduino 2 framework versions
# - https://github.com/platformio/platform-espressif8266/releases
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif8266
@@ -198,15 +198,10 @@ async def to_code(config):
cg.add_platformio_option("board_build.flash_mode", config[CONF_BOARD_FLASH_MODE])
ver: cv.Version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
cg.add_define(
"USE_ARDUINO_VERSION_CODE",
cg.RawExpression(f"VERSION_CODE({ver.major}, {ver.minor}, {ver.patch})"),
)
if config[CONF_BOARD] in ESP8266_FLASH_SIZES:
flash_size = ESP8266_FLASH_SIZES[config[CONF_BOARD]]
ld_scripts = ESP8266_LD_SCRIPTS[flash_size]
ver = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
if ver <= cv.Version(2, 3, 0):
# No ld script support
@@ -225,7 +220,7 @@ async def to_code(config):
def copy_files():
dir = os.path.dirname(__file__)
post_build_file = os.path.join(dir, "post_build.py.script")
post_build_file = os.path.join(dir, "post_build.py")
copy_file_if_changed(
post_build_file,
CORE.relative_build_path("post_build.py"),

View File

@@ -1,4 +1,4 @@
FLASH_SIZE_1_MB = 2**20
FLASH_SIZE_1_MB = 2 ** 20
FLASH_SIZE_512_KB = FLASH_SIZE_1_MB // 2
FLASH_SIZE_2_MB = 2 * FLASH_SIZE_1_MB
FLASH_SIZE_4_MB = 4 * FLASH_SIZE_1_MB

View File

@@ -98,18 +98,16 @@ static bool load_from_flash(size_t offset, uint32_t *data, size_t len) {
}
static bool save_to_rtc(size_t offset, const uint32_t *data, size_t len) {
for (uint32_t i = 0; i < len; i++) {
for (uint32_t i = 0; i < len; i++)
if (!esp_rtc_user_mem_write(offset + i, data[i]))
return false;
}
return true;
}
static bool load_from_rtc(size_t offset, uint32_t *data, size_t len) {
for (uint32_t i = 0; i < len; i++) {
for (uint32_t i = 0; i < len; i++)
if (!esp_rtc_user_mem_read(offset + i, &data[i]))
return false;
}
return true;
}

View File

@@ -2,10 +2,13 @@
#include "esp8266_pwm.h"
#include "esphome/core/macros.h"
#include "esphome/core/defines.h"
#include "esphome/core/log.h"
#include "esphome/core/helpers.h"
#if defined(USE_ESP8266) && ARDUINO_VERSION_CODE < VERSION_CODE(2, 4, 0)
#error ESP8266 PWM requires at least arduino_version 2.4.0
#endif
#include <core_esp8266_waveform.h>
namespace esphome {

View File

@@ -23,20 +23,15 @@ ESP8266PWM = esp8266_pwm_ns.class_("ESP8266PWM", output.FloatOutput, cg.Componen
SetFrequencyAction = esp8266_pwm_ns.class_("SetFrequencyAction", automation.Action)
validate_frequency = cv.All(cv.frequency, cv.Range(min=1.0e-6))
CONFIG_SCHEMA = cv.All(
output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.Required(CONF_ID): cv.declare_id(ESP8266PWM),
cv.Required(CONF_PIN): cv.All(
pins.internal_gpio_output_pin_schema, valid_pwm_pin
),
cv.Optional(CONF_FREQUENCY, default="1kHz"): validate_frequency,
}
).extend(cv.COMPONENT_SCHEMA),
cv.require_framework_version(
esp8266_arduino=cv.Version(2, 4, 0),
),
)
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.Required(CONF_ID): cv.declare_id(ESP8266PWM),
cv.Required(CONF_PIN): cv.All(
pins.internal_gpio_output_pin_schema, valid_pwm_pin
),
cv.Optional(CONF_FREQUENCY, default="1kHz"): validate_frequency,
}
).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):

View File

@@ -75,10 +75,9 @@ void EZOSensor::loop() {
return;
// some sensors return multiple comma-separated values, terminate string after first one
for (size_t i = 1; i < sizeof(buf) - 1; i++) {
for (size_t i = 1; i < sizeof(buf) - 1; i++)
if (buf[i] == ',')
buf[i] = '\0';
}
float val = parse_number<float>((char *) &buf[1]).value_or(0);
this->publish_state(val);

View File

@@ -19,7 +19,6 @@ from esphome.const import (
CONF_ON_TURN_ON,
CONF_TRIGGER_ID,
CONF_DIRECTION,
CONF_RESTORE_MODE,
)
from esphome.core import CORE, coroutine_with_priority
from esphome.cpp_helpers import setup_entity
@@ -27,24 +26,13 @@ from esphome.cpp_helpers import setup_entity
IS_PLATFORM_COMPONENT = True
fan_ns = cg.esphome_ns.namespace("fan")
Fan = fan_ns.class_("Fan", cg.EntityBase)
FanState = fan_ns.class_("Fan", Fan, cg.Component)
FanState = fan_ns.class_("FanState", cg.EntityBase, cg.Component)
MakeFan = cg.Application.struct("MakeFan")
FanDirection = fan_ns.enum("FanDirection", is_class=True)
FanDirection = fan_ns.enum("FanDirection")
FAN_DIRECTION_ENUM = {
"FORWARD": FanDirection.FORWARD,
"REVERSE": FanDirection.REVERSE,
}
FanRestoreMode = fan_ns.enum("FanRestoreMode", is_class=True)
RESTORE_MODES = {
"NO_RESTORE": FanRestoreMode.NO_RESTORE,
"ALWAYS_OFF": FanRestoreMode.ALWAYS_OFF,
"ALWAYS_ON": FanRestoreMode.ALWAYS_ON,
"RESTORE_DEFAULT_OFF": FanRestoreMode.RESTORE_DEFAULT_OFF,
"RESTORE_DEFAULT_ON": FanRestoreMode.RESTORE_DEFAULT_ON,
"RESTORE_INVERTED_DEFAULT_OFF": FanRestoreMode.RESTORE_INVERTED_DEFAULT_OFF,
"RESTORE_INVERTED_DEFAULT_ON": FanRestoreMode.RESTORE_INVERTED_DEFAULT_ON,
"FORWARD": FanDirection.FAN_DIRECTION_FORWARD,
"REVERSE": FanDirection.FAN_DIRECTION_REVERSE,
}
# Actions
@@ -62,10 +50,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(
RESTORE_MODES, upper=True, space="_"
),
cv.GenerateID(): cv.declare_id(FanState),
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),
cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All(
cv.requires_component("mqtt"), cv.publish_topic
@@ -107,8 +92,6 @@ FAN_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).exte
async def setup_fan_core_(var, config):
await setup_entity(var, config)
cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE]))
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
await mqtt.register_mqtt_component(mqtt_, config)
@@ -159,19 +142,19 @@ async def register_fan(var, config):
if not CORE.has_id(config[CONF_ID]):
var = cg.Pvariable(config[CONF_ID], var)
cg.add(cg.App.register_fan(var))
await cg.register_component(var, config)
await setup_fan_core_(var, config)
async def create_fan_state(config):
var = cg.new_Pvariable(config[CONF_ID])
await register_fan(var, config)
await cg.register_component(var, config)
return var
FAN_ACTION_SCHEMA = maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(Fan),
cv.Required(CONF_ID): cv.use_id(FanState),
}
)
@@ -193,7 +176,7 @@ async def fan_turn_off_to_code(config, action_id, template_arg, args):
TurnOnAction,
maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(Fan),
cv.Required(CONF_ID): cv.use_id(FanState),
cv.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
cv.Optional(CONF_SPEED): cv.templatable(cv.int_range(1)),
cv.Optional(CONF_DIRECTION): cv.templatable(
@@ -228,7 +211,7 @@ async def fan_cycle_speed_to_code(config, action_id, template_arg, args):
FanIsOnCondition,
automation.maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(Fan),
cv.Required(CONF_ID): cv.use_id(FanState),
}
),
)
@@ -237,7 +220,7 @@ async def fan_cycle_speed_to_code(config, action_id, template_arg, args):
FanIsOffCondition,
automation.maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(Fan),
cv.Required(CONF_ID): cv.use_id(FanState),
}
),
)

View File

@@ -0,0 +1,10 @@
#include "automation.h"
#include "esphome/core/log.h"
namespace esphome {
namespace fan {
static const char *const TAG = "fan.automation";
} // namespace fan
} // namespace esphome

View File

@@ -9,7 +9,7 @@ namespace fan {
template<typename... Ts> class TurnOnAction : public Action<Ts...> {
public:
explicit TurnOnAction(Fan *state) : state_(state) {}
explicit TurnOnAction(FanState *state) : state_(state) {}
TEMPLATABLE_VALUE(bool, oscillating)
TEMPLATABLE_VALUE(int, speed)
@@ -29,30 +29,30 @@ template<typename... Ts> class TurnOnAction : public Action<Ts...> {
call.perform();
}
Fan *state_;
FanState *state_;
};
template<typename... Ts> class TurnOffAction : public Action<Ts...> {
public:
explicit TurnOffAction(Fan *state) : state_(state) {}
explicit TurnOffAction(FanState *state) : state_(state) {}
void play(Ts... x) override { this->state_->turn_off().perform(); }
Fan *state_;
FanState *state_;
};
template<typename... Ts> class ToggleAction : public Action<Ts...> {
public:
explicit ToggleAction(Fan *state) : state_(state) {}
explicit ToggleAction(FanState *state) : state_(state) {}
void play(Ts... x) override { this->state_->toggle().perform(); }
Fan *state_;
FanState *state_;
};
template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
public:
explicit CycleSpeedAction(Fan *state) : state_(state) {}
explicit CycleSpeedAction(FanState *state) : state_(state) {}
void play(Ts... x) override {
// check to see if fan supports speeds and is on
@@ -83,29 +83,29 @@ template<typename... Ts> class CycleSpeedAction : public Action<Ts...> {
}
}
Fan *state_;
FanState *state_;
};
template<typename... Ts> class FanIsOnCondition : public Condition<Ts...> {
public:
explicit FanIsOnCondition(Fan *state) : state_(state) {}
explicit FanIsOnCondition(FanState *state) : state_(state) {}
bool check(Ts... x) override { return this->state_->state; }
protected:
Fan *state_;
FanState *state_;
};
template<typename... Ts> class FanIsOffCondition : public Condition<Ts...> {
public:
explicit FanIsOffCondition(Fan *state) : state_(state) {}
explicit FanIsOffCondition(FanState *state) : state_(state) {}
bool check(Ts... x) override { return !this->state_->state; }
protected:
Fan *state_;
FanState *state_;
};
class FanTurnOnTrigger : public Trigger<> {
public:
FanTurnOnTrigger(Fan *state) {
FanTurnOnTrigger(FanState *state) {
state->add_on_state_callback([this, state]() {
auto is_on = state->state;
auto should_trigger = is_on && !this->last_on_;
@@ -123,7 +123,7 @@ class FanTurnOnTrigger : public Trigger<> {
class FanTurnOffTrigger : public Trigger<> {
public:
FanTurnOffTrigger(Fan *state) {
FanTurnOffTrigger(FanState *state) {
state->add_on_state_callback([this, state]() {
auto is_on = state->state;
auto should_trigger = !is_on && this->last_on_;
@@ -141,7 +141,7 @@ class FanTurnOffTrigger : public Trigger<> {
class FanSpeedSetTrigger : public Trigger<> {
public:
FanSpeedSetTrigger(Fan *state) {
FanSpeedSetTrigger(FanState *state) {
state->add_on_state_callback([this, state]() {
auto speed = state->speed;
auto should_trigger = speed != !this->last_speed_;

View File

@@ -1,175 +0,0 @@
#include "fan.h"
#include "fan_helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace fan {
static const char *const TAG = "fan";
const LogString *fan_direction_to_string(FanDirection direction) {
switch (direction) {
case FanDirection::FORWARD:
return LOG_STR("FORWARD");
case FanDirection::REVERSE:
return LOG_STR("REVERSE");
default:
return LOG_STR("UNKNOWN");
}
}
void FanCall::perform() {
ESP_LOGD(TAG, "'%s' - Setting:", this->parent_.get_name().c_str());
this->validate_();
if (this->binary_state_.has_value())
ESP_LOGD(TAG, " State: %s", ONOFF(*this->binary_state_));
if (this->oscillating_.has_value())
ESP_LOGD(TAG, " Oscillating: %s", YESNO(*this->oscillating_));
if (this->speed_.has_value())
ESP_LOGD(TAG, " Speed: %d", *this->speed_);
if (this->direction_.has_value())
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(*this->direction_)));
this->parent_.control(*this);
}
void FanCall::validate_() {
auto traits = this->parent_.get_traits();
if (this->speed_.has_value())
this->speed_ = clamp(*this->speed_, 1, traits.supported_speed_count());
if (this->binary_state_.has_value() && *this->binary_state_) {
// when turning on, if current speed is zero, set speed to 100%
if (traits.supports_speed() && !this->parent_.state && this->parent_.speed == 0) {
this->speed_ = traits.supported_speed_count();
}
}
if (this->oscillating_.has_value() && !traits.supports_oscillation()) {
ESP_LOGW(TAG, "'%s' - This fan does not support oscillation!", this->parent_.get_name().c_str());
this->oscillating_.reset();
}
if (this->speed_.has_value() && !traits.supports_speed()) {
ESP_LOGW(TAG, "'%s' - This fan does not support speeds!", this->parent_.get_name().c_str());
this->speed_.reset();
}
if (this->direction_.has_value() && !traits.supports_direction()) {
ESP_LOGW(TAG, "'%s' - This fan does not support directions!", this->parent_.get_name().c_str());
this->direction_.reset();
}
}
// This whole method is deprecated, don't warn about usage of deprecated methods inside of it.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
FanCall &FanCall::set_speed(const char *legacy_speed) {
const auto supported_speed_count = this->parent_.get_traits().supported_speed_count();
if (strcasecmp(legacy_speed, "low") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_LOW, supported_speed_count));
} else if (strcasecmp(legacy_speed, "medium") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_MEDIUM, supported_speed_count));
} else if (strcasecmp(legacy_speed, "high") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_HIGH, supported_speed_count));
}
return *this;
}
#pragma GCC diagnostic pop
FanCall FanRestoreState::to_call(Fan &fan) {
auto call = fan.make_call();
call.set_state(this->state);
call.set_oscillating(this->oscillating);
call.set_speed(this->speed);
call.set_direction(this->direction);
return call;
}
void FanRestoreState::apply(Fan &fan) {
fan.state = this->state;
fan.oscillating = this->oscillating;
fan.speed = this->speed;
fan.direction = this->direction;
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); }
FanCall Fan::make_call() { return FanCall(*this); }
void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
void Fan::publish_state() {
auto traits = this->get_traits();
ESP_LOGD(TAG, "'%s' - Sending state:", this->name_.c_str());
ESP_LOGD(TAG, " State: %s", ONOFF(this->state));
if (traits.supports_speed())
ESP_LOGD(TAG, " Speed: %d", this->speed);
if (traits.supports_oscillation())
ESP_LOGD(TAG, " Oscillating: %s", YESNO(this->oscillating));
if (traits.supports_direction())
ESP_LOGD(TAG, " Direction: %s", LOG_STR_ARG(fan_direction_to_string(this->direction)));
this->state_callback_.call();
this->save_state_();
}
// Random 32-bit value, change this every time the layout of the FanRestoreState struct changes.
constexpr uint32_t RESTORE_STATE_VERSION = 0x71700ABA;
optional<FanRestoreState> Fan::restore_state_() {
FanRestoreState recovered{};
this->rtc_ = global_preferences->make_preference<FanRestoreState>(this->get_object_id_hash() ^ RESTORE_STATE_VERSION);
bool restored = this->rtc_.load(&recovered);
switch (this->restore_mode_) {
case FanRestoreMode::NO_RESTORE:
return {};
case FanRestoreMode::ALWAYS_OFF:
recovered.state = false;
return recovered;
case FanRestoreMode::ALWAYS_ON:
recovered.state = true;
return recovered;
case FanRestoreMode::RESTORE_DEFAULT_OFF:
recovered.state = restored ? recovered.state : false;
return recovered;
case FanRestoreMode::RESTORE_DEFAULT_ON:
recovered.state = restored ? recovered.state : true;
return recovered;
case FanRestoreMode::RESTORE_INVERTED_DEFAULT_OFF:
recovered.state = restored ? !recovered.state : false;
return recovered;
case FanRestoreMode::RESTORE_INVERTED_DEFAULT_ON:
recovered.state = restored ? !recovered.state : true;
return recovered;
}
return {};
}
void Fan::save_state_() {
FanRestoreState state{};
state.state = this->state;
state.oscillating = this->oscillating;
state.speed = this->speed;
state.direction = this->direction;
this->rtc_.save(&state);
}
void Fan::dump_traits_(const char *tag, const char *prefix) {
if (this->get_traits().supports_speed()) {
ESP_LOGCONFIG(tag, "%s Speed: YES", prefix);
ESP_LOGCONFIG(tag, "%s Speed count: %d", prefix, this->get_traits().supported_speed_count());
}
if (this->get_traits().supports_oscillation())
ESP_LOGCONFIG(tag, "%s Oscillation: YES", prefix);
if (this->get_traits().supports_direction())
ESP_LOGCONFIG(tag, "%s Direction: YES", prefix);
}
uint32_t Fan::hash_base() { return 418001110UL; }
} // namespace fan
} // namespace esphome

View File

@@ -1,154 +0,0 @@
#pragma once
#include "esphome/core/entity_base.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include "esphome/core/optional.h"
#include "esphome/core/preferences.h"
#include "fan_traits.h"
namespace esphome {
namespace fan {
#define LOG_FAN(prefix, type, obj) \
if ((obj) != nullptr) { \
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
(obj)->dump_traits_(TAG, prefix); \
}
/// Simple enum to represent the speed of a fan. - DEPRECATED - Will be deleted soon
enum ESPDEPRECATED("FanSpeed is deprecated.", "2021.9") FanSpeed {
FAN_SPEED_LOW = 0, ///< The fan is running on low speed.
FAN_SPEED_MEDIUM = 1, ///< The fan is running on medium speed.
FAN_SPEED_HIGH = 2 ///< The fan is running on high/full speed.
};
/// Simple enum to represent the direction of a fan.
enum class FanDirection { FORWARD = 0, REVERSE = 1 };
/// Restore mode of a fan.
enum class FanRestoreMode {
NO_RESTORE,
ALWAYS_OFF,
ALWAYS_ON,
RESTORE_DEFAULT_OFF,
RESTORE_DEFAULT_ON,
RESTORE_INVERTED_DEFAULT_OFF,
RESTORE_INVERTED_DEFAULT_ON,
};
const LogString *fan_direction_to_string(FanDirection direction);
class Fan;
class FanCall {
public:
explicit FanCall(Fan &parent) : parent_(parent) {}
FanCall &set_state(bool binary_state) {
this->binary_state_ = binary_state;
return *this;
}
FanCall &set_state(optional<bool> binary_state) {
this->binary_state_ = binary_state;
return *this;
}
optional<bool> get_state() const { return this->binary_state_; }
FanCall &set_oscillating(bool oscillating) {
this->oscillating_ = oscillating;
return *this;
}
FanCall &set_oscillating(optional<bool> oscillating) {
this->oscillating_ = oscillating;
return *this;
}
optional<bool> get_oscillating() const { return this->oscillating_; }
FanCall &set_speed(int speed) {
this->speed_ = speed;
return *this;
}
ESPDEPRECATED("set_speed() with string argument is deprecated, use integer argument instead.", "2021.9")
FanCall &set_speed(const char *legacy_speed);
optional<int> get_speed() const { return this->speed_; }
FanCall &set_direction(FanDirection direction) {
this->direction_ = direction;
return *this;
}
FanCall &set_direction(optional<FanDirection> direction) {
this->direction_ = direction;
return *this;
}
optional<FanDirection> get_direction() const { return this->direction_; }
void perform();
protected:
void validate_();
Fan &parent_;
optional<bool> binary_state_;
optional<bool> oscillating_;
optional<int> speed_;
optional<FanDirection> direction_{};
};
struct FanRestoreState {
bool state;
int speed;
bool oscillating;
FanDirection direction;
/// Convert this struct to a fan call that can be performed.
FanCall to_call(Fan &fan);
/// Apply these settings to the fan.
void apply(Fan &fan);
} __attribute__((packed));
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.
bool oscillating{false};
/// The current fan speed level
int speed{0};
/// The current direction of the fan
FanDirection direction{FanDirection::FORWARD};
FanCall turn_on();
FanCall turn_off();
FanCall toggle();
FanCall make_call();
/// Register a callback that will be called each time the state changes.
void add_on_state_callback(std::function<void()> &&callback);
void publish_state();
virtual FanTraits get_traits() = 0;
/// Set the restore mode of this fan.
void set_restore_mode(FanRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
protected:
friend FanCall;
virtual void control(const FanCall &call) = 0;
optional<FanRestoreState> restore_state_();
void save_state_();
void dump_traits_(const char *tag, const char *prefix);
uint32_t hash_base() override;
CallbackManager<void()> state_callback_{};
ESPPreferenceObject rtc_;
FanRestoreMode restore_mode_;
};
} // namespace fan
} // namespace esphome

View File

@@ -1,6 +1,5 @@
#pragma once
#include "fan.h"
#include "fan_state.h"
namespace esphome {
namespace fan {

View File

@@ -1,16 +1,85 @@
#include "fan_state.h"
#include "fan_helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace fan {
static const char *const TAG = "fan";
const FanTraits &FanState::get_traits() const { return this->traits_; }
void FanState::set_traits(const FanTraits &traits) { this->traits_ = traits; }
void FanState::add_on_state_callback(std::function<void()> &&callback) {
this->state_callback_.add(std::move(callback));
}
FanState::FanState(const std::string &name) : EntityBase(name) {}
FanStateCall FanState::turn_on() { return this->make_call().set_state(true); }
FanStateCall FanState::turn_off() { return this->make_call().set_state(false); }
FanStateCall FanState::toggle() { return this->make_call().set_state(!this->state); }
FanStateCall FanState::make_call() { return FanStateCall(this); }
struct FanStateRTCState {
bool state;
int speed;
bool oscillating;
FanDirection direction;
};
void FanState::setup() {
auto restore = this->restore_state_();
if (restore)
restore->to_call(*this).perform();
this->rtc_ = global_preferences->make_preference<FanStateRTCState>(this->get_object_id_hash());
FanStateRTCState recovered{};
if (!this->rtc_.load(&recovered))
return;
auto call = this->make_call();
call.set_state(recovered.state);
call.set_speed(recovered.speed);
call.set_oscillating(recovered.oscillating);
call.set_direction(recovered.direction);
call.perform();
}
float FanState::get_setup_priority() const { return setup_priority::DATA - 1.0f; }
uint32_t FanState::hash_base() { return 418001110UL; }
void FanStateCall::perform() const {
if (this->binary_state_.has_value()) {
this->state_->state = *this->binary_state_;
}
if (this->oscillating_.has_value()) {
this->state_->oscillating = *this->oscillating_;
}
if (this->direction_.has_value()) {
this->state_->direction = *this->direction_;
}
if (this->speed_.has_value()) {
const int speed_count = this->state_->get_traits().supported_speed_count();
this->state_->speed = clamp(*this->speed_, 1, speed_count);
}
FanStateRTCState saved{};
saved.state = this->state_->state;
saved.speed = this->state_->speed;
saved.oscillating = this->state_->oscillating;
saved.direction = this->state_->direction;
this->state_->rtc_.save(&saved);
this->state_->state_callback_.call();
}
// This whole method is deprecated, don't warn about usage of deprecated methods inside of it.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
FanStateCall &FanStateCall::set_speed(const char *legacy_speed) {
const auto supported_speed_count = this->state_->get_traits().supported_speed_count();
if (strcasecmp(legacy_speed, "low") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_LOW, supported_speed_count));
} else if (strcasecmp(legacy_speed, "medium") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_MEDIUM, supported_speed_count));
} else if (strcasecmp(legacy_speed, "high") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_HIGH, supported_speed_count));
}
return *this;
}
} // namespace fan
} // namespace esphome

View File

@@ -1,34 +1,111 @@
#pragma once
#include "esphome/core/component.h"
#include "fan.h"
#include "esphome/core/entity_base.h"
#include "esphome/core/helpers.h"
#include "esphome/core/preferences.h"
#include "esphome/core/log.h"
#include "fan_traits.h"
namespace esphome {
namespace fan {
enum ESPDEPRECATED("LegacyFanDirection members are deprecated, use FanDirection instead.",
"2022.2") LegacyFanDirection {
FAN_DIRECTION_FORWARD = 0,
FAN_DIRECTION_REVERSE = 1
/// Simple enum to represent the speed of a fan. - DEPRECATED - Will be deleted soon
enum ESPDEPRECATED("FanSpeed is deprecated.", "2021.9") FanSpeed {
FAN_SPEED_LOW = 0, ///< The fan is running on low speed.
FAN_SPEED_MEDIUM = 1, ///< The fan is running on medium speed.
FAN_SPEED_HIGH = 2 ///< The fan is running on high/full speed.
};
class ESPDEPRECATED("FanState is deprecated, use Fan instead.", "2022.2") FanState : public Fan, public Component {
/// Simple enum to represent the direction of a fan
enum FanDirection { FAN_DIRECTION_FORWARD = 0, FAN_DIRECTION_REVERSE = 1 };
class FanState;
class FanStateCall {
public:
explicit FanStateCall(FanState *state) : state_(state) {}
FanStateCall &set_state(bool binary_state) {
this->binary_state_ = binary_state;
return *this;
}
FanStateCall &set_state(optional<bool> binary_state) {
this->binary_state_ = binary_state;
return *this;
}
FanStateCall &set_oscillating(bool oscillating) {
this->oscillating_ = oscillating;
return *this;
}
FanStateCall &set_oscillating(optional<bool> oscillating) {
this->oscillating_ = oscillating;
return *this;
}
FanStateCall &set_speed(int speed) {
this->speed_ = speed;
return *this;
}
ESPDEPRECATED("set_speed() with string argument is deprecated, use integer argument instead.", "2021.9")
FanStateCall &set_speed(const char *legacy_speed);
FanStateCall &set_direction(FanDirection direction) {
this->direction_ = direction;
return *this;
}
FanStateCall &set_direction(optional<FanDirection> direction) {
this->direction_ = direction;
return *this;
}
void perform() const;
protected:
FanState *const state_;
optional<bool> binary_state_;
optional<bool> oscillating_;
optional<int> speed_;
optional<FanDirection> direction_{};
};
class FanState : public EntityBase, public Component {
public:
FanState() = default;
explicit FanState(const std::string &name) : Fan(name) {}
/// Construct the fan state with name.
explicit FanState(const std::string &name);
/// Get the traits of this fan.
FanTraits get_traits() override { return this->traits_; }
/// Register a callback that will be called each time the state changes.
void add_on_state_callback(std::function<void()> &&callback);
/// Get the traits of this fan (i.e. what features it supports).
const FanTraits &get_traits() const;
/// Set the traits of this fan (i.e. what features it supports).
void set_traits(const FanTraits &traits) { this->traits_ = traits; }
void set_traits(const FanTraits &traits);
/// The current ON/OFF state of the fan.
bool state{false};
/// The current oscillation state of the fan.
bool oscillating{false};
/// The current fan speed level
int speed{};
/// The current direction of the fan
FanDirection direction{FAN_DIRECTION_FORWARD};
FanStateCall turn_on();
FanStateCall turn_off();
FanStateCall toggle();
FanStateCall make_call();
void setup() override;
float get_setup_priority() const override;
protected:
void control(const FanCall &call) override { this->publish_state(); }
friend FanStateCall;
uint32_t hash_base() override;
FanTraits traits_{};
CallbackManager<void()> state_callback_{};
ESPPreferenceObject rtc_;
};
} // namespace fan

View File

@@ -80,10 +80,6 @@ AURA_LED_COLORS = {
"RED": AuraLEDColor.RED,
"BLUE": AuraLEDColor.BLUE,
"PURPLE": AuraLEDColor.PURPLE,
"GREEN": AuraLEDColor.GREEN,
"YELLOW": AuraLEDColor.YELLOW,
"CYAN": AuraLEDColor.CYAN,
"WHITE": AuraLEDColor.WHITE,
}
validate_aura_led_colors = cv.enum(AURA_LED_COLORS, upper=True)

View File

@@ -278,11 +278,10 @@ void FingerprintGrowComponent::delete_all_fingerprints() {
void FingerprintGrowComponent::led_control(bool state) {
ESP_LOGD(TAG, "Setting LED");
if (state) {
if (state)
this->data_ = {LED_ON};
} else {
else
this->data_ = {LED_OFF};
}
switch (this->send_command_()) {
case OK:
ESP_LOGD(TAG, "LED set");

View File

@@ -76,10 +76,6 @@ enum GrowAuraLEDColor {
RED = 0x01,
BLUE = 0x02,
PURPLE = 0x03,
GREEN = 0x04,
YELLOW = 0x05,
CYAN = 0x06,
WHITE = 0x07,
};
class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevice {

View File

@@ -207,7 +207,7 @@ void FujitsuGeneralClimate::transmit_(uint8_t const *message, uint8_t length) {
ESP_LOGV(TAG, "Transmit message length %d", length);
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(FUJITSU_GENERAL_CARRIER_FREQUENCY);

View File

@@ -33,18 +33,16 @@ void GPIOSwitch::setup() {
}
// write state before setup
if (initial_state) {
if (initial_state)
this->turn_on();
} else {
else
this->turn_off();
}
this->pin_->setup();
// write after setup again for other IOs
if (initial_state) {
if (initial_state)
this->turn_on();
} else {
else
this->turn_off();
}
}
void GPIOSwitch::dump_config() {
LOG_SWITCH("", "GPIO Switch", this);

View File

@@ -115,7 +115,7 @@ class GraphTrace {
void set_line_type(enum LineType val) { this->line_type_ = val; }
Color get_line_color() { return this->line_color_; }
void set_line_color(Color val) { this->line_color_ = val; }
std::string get_name() { return name_; }
const std::string get_name() { return name_; }
const HistoryData *get_tracedata() { return &data_; }
protected:

View File

@@ -17,7 +17,7 @@ from .. import hbridge_ns
CODEOWNERS = ["@WeekendWarrior"]
HBridgeFan = hbridge_ns.class_("HBridgeFan", cg.Component, fan.Fan)
HBridgeFan = hbridge_ns.class_("HBridgeFan", fan.FanState)
DecayMode = hbridge_ns.enum("DecayMode")
DECAY_MODE_OPTIONS = {
@@ -59,7 +59,6 @@ async def to_code(config):
config[CONF_SPEED_COUNT],
config[CONF_DECAY_MODE],
)
await cg.register_component(var, config)
await fan.register_fan(var, config)
pin_a_ = await cg.get_variable(config[CONF_PIN_A])
cg.add(var.set_pin_a(pin_a_))

View File

@@ -22,49 +22,47 @@ void HBridgeFan::set_hbridge_levels_(float a_level, float b_level, float enable)
ESP_LOGD(TAG, "Setting speed: a: %.2f, b: %.2f, enable: %.2f", a_level, b_level, enable);
}
fan::FanCall HBridgeFan::brake() {
fan::FanStateCall HBridgeFan::brake() {
ESP_LOGD(TAG, "Braking");
(this->enable_ == nullptr) ? this->set_hbridge_levels_(1.0f, 1.0f) : this->set_hbridge_levels_(1.0f, 1.0f, 1.0f);
return this->make_call().set_state(false);
}
void HBridgeFan::setup() {
auto restore = this->restore_state_();
if (restore.has_value()) {
restore->apply(*this);
this->write_state_();
}
}
void HBridgeFan::dump_config() {
LOG_FAN("", "H-Bridge Fan", this);
ESP_LOGCONFIG(TAG, "Fan '%s':", this->get_name().c_str());
if (this->get_traits().supports_oscillation()) {
ESP_LOGCONFIG(TAG, " Oscillation: YES");
}
if (this->get_traits().supports_direction()) {
ESP_LOGCONFIG(TAG, " Direction: YES");
}
if (this->decay_mode_ == DECAY_MODE_SLOW) {
ESP_LOGCONFIG(TAG, " Decay Mode: Slow");
} else {
ESP_LOGCONFIG(TAG, " Decay Mode: Fast");
}
}
fan::FanTraits HBridgeFan::get_traits() {
return fan::FanTraits(this->oscillating_ != nullptr, true, true, this->speed_count_);
void HBridgeFan::setup() {
auto traits = fan::FanTraits(this->oscillating_ != nullptr, true, true, this->speed_count_);
this->set_traits(traits);
this->add_on_state_callback([this]() { this->next_update_ = true; });
}
void HBridgeFan::control(const fan::FanCall &call) {
if (call.get_state().has_value())
this->state = *call.get_state();
if (call.get_speed().has_value())
this->speed = *call.get_speed();
if (call.get_oscillating().has_value())
this->oscillating = *call.get_oscillating();
if (call.get_direction().has_value())
this->direction = *call.get_direction();
void HBridgeFan::loop() {
if (!this->next_update_) {
return;
}
this->next_update_ = false;
this->write_state_();
this->publish_state();
}
void HBridgeFan::write_state_() {
float speed = this->state ? static_cast<float>(this->speed) / static_cast<float>(this->speed_count_) : 0.0f;
float speed = 0.0f;
if (this->state) {
speed = static_cast<float>(this->speed) / static_cast<float>(this->speed_count_);
}
if (speed == 0.0f) { // off means idle
(this->enable_ == nullptr) ? this->set_hbridge_levels_(speed, speed)
: this->set_hbridge_levels_(speed, speed, speed);
} else if (this->direction == fan::FanDirection::FORWARD) {
return;
}
if (this->direction == fan::FAN_DIRECTION_FORWARD) {
if (this->decay_mode_ == DECAY_MODE_SLOW) {
(this->enable_ == nullptr) ? this->set_hbridge_levels_(1.0f - speed, 1.0f)
: this->set_hbridge_levels_(1.0f - speed, 1.0f, 1.0f);
@@ -81,9 +79,6 @@ void HBridgeFan::write_state_() {
: this->set_hbridge_levels_(1.0f, 0.0f, speed);
}
}
if (this->oscillating_ != nullptr)
this->oscillating_->set_state(this->oscillating);
}
} // namespace hbridge

View File

@@ -3,7 +3,7 @@
#include "esphome/core/automation.h"
#include "esphome/components/output/binary_output.h"
#include "esphome/components/output/float_output.h"
#include "esphome/components/fan/fan.h"
#include "esphome/components/fan/fan_state.h"
namespace esphome {
namespace hbridge {
@@ -13,7 +13,7 @@ enum DecayMode {
DECAY_MODE_FAST = 1,
};
class HBridgeFan : public Component, public fan::Fan {
class HBridgeFan : public fan::FanState {
public:
HBridgeFan(int speed_count, DecayMode decay_mode) : speed_count_(speed_count), decay_mode_(decay_mode) {}
@@ -22,22 +22,25 @@ class HBridgeFan : public Component, public fan::Fan {
void set_enable_pin(output::FloatOutput *enable) { enable_ = enable; }
void setup() override;
void loop() override;
void dump_config() override;
fan::FanTraits get_traits() override;
float get_setup_priority() const override { return setup_priority::HARDWARE; }
fan::FanCall brake();
fan::FanStateCall brake();
int get_speed_count() { return this->speed_count_; }
// update Hbridge without a triggered FanState change, eg. for acceleration/deceleration ramping
void internal_update() { this->next_update_ = true; }
protected:
output::FloatOutput *pin_a_;
output::FloatOutput *pin_b_;
output::FloatOutput *enable_{nullptr};
output::BinaryOutput *oscillating_{nullptr};
bool next_update_{true};
int speed_count_{};
DecayMode decay_mode_{DECAY_MODE_SLOW};
void control(const fan::FanCall &call) override;
void write_state_();
void set_hbridge_levels_(float a_level, float b_level);
void set_hbridge_levels_(float a_level, float b_level, float enable);
};

View File

@@ -6,20 +6,20 @@ namespace esphome {
namespace heatpumpir {
void IRSenderESPHome::setFrequency(int frequency) { // NOLINT(readability-identifier-naming)
auto *data = transmit_.get_data();
auto data = transmit_.get_data();
data->set_carrier_frequency(1000 * frequency);
}
// Send an IR 'mark' symbol, i.e. transmitter ON
void IRSenderESPHome::mark(int mark_length) {
auto *data = transmit_.get_data();
auto data = transmit_.get_data();
data->mark(mark_length);
}
// Send an IR 'space' symbol, i.e. transmitter OFF
void IRSenderESPHome::space(int space_length) {
if (space_length) {
auto *data = transmit_.get_data();
auto data = transmit_.get_data();
data->space(space_length);
} else {
transmit_.perform();

View File

@@ -19,11 +19,10 @@ void set_bits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, con
void set_bit(uint8_t *const data, const uint8_t position, const bool on) {
uint8_t mask = 1 << position;
if (on) {
if (on)
*data |= mask;
} else {
else
*data &= ~mask;
}
}
uint8_t *invert_byte_pairs(uint8_t *ptr, const uint16_t length) {
@@ -70,11 +69,10 @@ void HitachiClimate::set_temp_(uint8_t celsius, bool set_previous) {
temp = std::min(celsius, HITACHI_AC344_TEMP_MAX);
temp = std::max(temp, HITACHI_AC344_TEMP_MIN);
set_bits(&remote_state_[HITACHI_AC344_TEMP_BYTE], HITACHI_AC344_TEMP_OFFSET, HITACHI_AC344_TEMP_SIZE, temp);
if (previous_temp_ > temp) {
if (previous_temp_ > temp)
set_button_(HITACHI_AC344_BUTTON_TEMP_DOWN);
} else if (previous_temp_ < temp) {
else if (previous_temp_ < temp)
set_button_(HITACHI_AC344_BUTTON_TEMP_UP);
}
if (set_previous)
previous_temp_ = temp;
}
@@ -112,12 +110,11 @@ void HitachiClimate::set_fan_(uint8_t speed) {
void HitachiClimate::set_swing_v_toggle_(bool on) {
uint8_t button = get_button_(); // Get the current button value.
if (on) {
button = HITACHI_AC344_BUTTON_SWINGV; // Set the button to SwingV.
} else if (button == HITACHI_AC344_BUTTON_SWINGV) { // Asked to unset it
if (on)
button = HITACHI_AC344_BUTTON_SWINGV; // Set the button to SwingV.
else if (button == HITACHI_AC344_BUTTON_SWINGV) // Asked to unset it
// It was set previous, so use Power as a default
button = HITACHI_AC344_BUTTON_POWER;
}
set_button_(button);
}
@@ -214,7 +211,7 @@ void HitachiClimate::transmit_state() {
invert_byte_pairs(remote_state_ + 3, HITACHI_AC344_STATE_LENGTH - 3);
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(HITACHI_AC344_FREQ);
uint8_t repeat = 0;
@@ -323,9 +320,9 @@ bool HitachiClimate::on_receive(remote_base::RemoteReceiveData data) {
for (uint8_t pos = 0; pos < HITACHI_AC344_STATE_LENGTH; pos++) {
// Read bit
for (int8_t bit = 0; bit < 8; bit++) {
if (data.expect_item(HITACHI_AC344_BIT_MARK, HITACHI_AC344_ONE_SPACE)) {
if (data.expect_item(HITACHI_AC344_BIT_MARK, HITACHI_AC344_ONE_SPACE))
recv_state[pos] |= 1 << bit;
} else if (!data.expect_item(HITACHI_AC344_BIT_MARK, HITACHI_AC344_ZERO_SPACE)) {
else if (!data.expect_item(HITACHI_AC344_BIT_MARK, HITACHI_AC344_ZERO_SPACE)) {
ESP_LOGVV(TAG, "Byte %d bit %d fail", pos, bit);
return false;
}

View File

@@ -19,11 +19,10 @@ void set_bits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, con
void set_bit(uint8_t *const data, const uint8_t position, const bool on) {
uint8_t mask = 1 << position;
if (on) {
if (on)
*data |= mask;
} else {
else
*data &= ~mask;
}
}
uint8_t *invert_byte_pairs(uint8_t *ptr, const uint16_t length) {
@@ -70,11 +69,10 @@ void HitachiClimate::set_temp_(uint8_t celsius, bool set_previous) {
temp = std::min(celsius, HITACHI_AC424_TEMP_MAX);
temp = std::max(temp, HITACHI_AC424_TEMP_MIN);
set_bits(&remote_state_[HITACHI_AC424_TEMP_BYTE], HITACHI_AC424_TEMP_OFFSET, HITACHI_AC424_TEMP_SIZE, temp);
if (previous_temp_ > temp) {
if (previous_temp_ > temp)
set_button_(HITACHI_AC424_BUTTON_TEMP_DOWN);
} else if (previous_temp_ < temp) {
else if (previous_temp_ < temp)
set_button_(HITACHI_AC424_BUTTON_TEMP_UP);
}
if (set_previous)
previous_temp_ = temp;
}
@@ -112,12 +110,11 @@ void HitachiClimate::set_fan_(uint8_t speed) {
void HitachiClimate::set_swing_v_toggle_(bool on) {
uint8_t button = get_button_(); // Get the current button value.
if (on) {
button = HITACHI_AC424_BUTTON_SWINGV; // Set the button to SwingV.
} else if (button == HITACHI_AC424_BUTTON_SWINGV) { // Asked to unset it
if (on)
button = HITACHI_AC424_BUTTON_SWINGV; // Set the button to SwingV.
else if (button == HITACHI_AC424_BUTTON_SWINGV) // Asked to unset it
// It was set previous, so use Power as a default
button = HITACHI_AC424_BUTTON_POWER;
}
set_button_(button);
}
@@ -215,7 +212,7 @@ void HitachiClimate::transmit_state() {
invert_byte_pairs(remote_state_ + 3, HITACHI_AC424_STATE_LENGTH - 3);
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(HITACHI_AC424_FREQ);
uint8_t repeat = 0;
@@ -324,9 +321,9 @@ bool HitachiClimate::on_receive(remote_base::RemoteReceiveData data) {
for (uint8_t pos = 0; pos < HITACHI_AC424_STATE_LENGTH; pos++) {
// Read bit
for (int8_t bit = 0; bit < 8; bit++) {
if (data.expect_item(HITACHI_AC424_BIT_MARK, HITACHI_AC424_ONE_SPACE)) {
if (data.expect_item(HITACHI_AC424_BIT_MARK, HITACHI_AC424_ONE_SPACE))
recv_state[pos] |= 1 << bit;
} else if (!data.expect_item(HITACHI_AC424_BIT_MARK, HITACHI_AC424_ZERO_SPACE)) {
else if (!data.expect_item(HITACHI_AC424_BIT_MARK, HITACHI_AC424_ZERO_SPACE)) {
ESP_LOGVV(TAG, "Byte %d bit %d fail", pos, bit);
return false;
}

View File

@@ -44,8 +44,8 @@ class HM3301Component : public PollingComponent, public i2c::I2CDevice {
AQICalculatorType aqi_calc_type_;
AQICalculatorFactory aqi_calculator_factory_ = AQICalculatorFactory();
bool validate_checksum_(const uint8_t *data);
uint16_t get_sensor_value_(const uint8_t *data, uint8_t i);
bool validate_checksum_(const uint8_t *);
uint16_t get_sensor_value_(const uint8_t *, uint8_t);
};
} // namespace hm3301

View File

@@ -25,11 +25,10 @@ void HomeassistantBinarySensor::setup() {
} else {
ESP_LOGD(TAG, "'%s': Got state %s", this->entity_id_.c_str(), ONOFF(new_state));
}
if (this->initial_) {
if (this->initial_)
this->publish_initial_state(new_state);
} else {
else
this->publish_state(new_state);
}
break;
}
this->initial_ = false;

View File

@@ -31,8 +31,6 @@ CONF_BODY = "body"
CONF_JSON = "json"
CONF_VERIFY_SSL = "verify_ssl"
CONF_ON_RESPONSE = "on_response"
CONF_FOLLOW_REDIRECTS = "follow_redirects"
CONF_REDIRECT_LIMIT = "redirect_limit"
def validate_url(value):
@@ -73,8 +71,6 @@ CONFIG_SCHEMA = cv.All(
{
cv.GenerateID(): cv.declare_id(HttpRequestComponent),
cv.Optional(CONF_USERAGENT, "ESPHome"): cv.string,
cv.Optional(CONF_FOLLOW_REDIRECTS, True): cv.boolean,
cv.Optional(CONF_REDIRECT_LIMIT, 3): cv.int_,
cv.Optional(
CONF_TIMEOUT, default="5s"
): cv.positive_time_period_milliseconds,
@@ -94,9 +90,6 @@ async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_timeout(config[CONF_TIMEOUT]))
cg.add(var.set_useragent(config[CONF_USERAGENT]))
cg.add(var.set_follow_redirects(config[CONF_FOLLOW_REDIRECTS]))
cg.add(var.set_redirect_limit(config[CONF_REDIRECT_LIMIT]))
if CORE.is_esp8266 and not config[CONF_ESP8266_DISABLE_SSL_SUPPORT]:
cg.add_define("USE_HTTP_REQUEST_ESP8266_HTTPS")

View File

@@ -1,7 +1,7 @@
#ifdef USE_ARDUINO
#include "http_request.h"
#include "esphome/core/defines.h"
#include "esphome/core/macros.h"
#include "esphome/core/log.h"
#include "esphome/components/network/util.h"
@@ -14,8 +14,6 @@ void HttpRequestComponent::dump_config() {
ESP_LOGCONFIG(TAG, "HTTP Request:");
ESP_LOGCONFIG(TAG, " Timeout: %ums", this->timeout_);
ESP_LOGCONFIG(TAG, " User-Agent: %s", this->useragent_);
ESP_LOGCONFIG(TAG, " Follow Redirects: %d", this->follow_redirects_);
ESP_LOGCONFIG(TAG, " Redirect limit: %d", this->redirect_limit_);
}
void HttpRequestComponent::set_url(std::string url) {
@@ -40,21 +38,18 @@ void HttpRequestComponent::send(const std::vector<HttpRequestResponseTrigger *>
bool begin_status = false;
const String url = this->url_.c_str();
#if defined(USE_ESP32) || (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0))
#if defined(USE_ESP32) || USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0)
if (this->follow_redirects_) {
this->client_.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
} else {
this->client_.setFollowRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS);
}
#else
this->client_.setFollowRedirects(this->follow_redirects_);
#endif
this->client_.setRedirectLimit(this->redirect_limit_);
#endif
#if defined(USE_ESP32)
#ifdef USE_ESP32
begin_status = this->client_.begin(url);
#elif defined(USE_ESP8266)
#endif
#ifdef USE_ESP8266
#if ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0)
this->client_.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
#elif ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
this->client_.setFollowRedirects(true);
#endif
#if ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
this->client_.setRedirectLimit(3);
#endif
begin_status = this->client_.begin(*this->get_wifi_client_(), url);
#endif

View File

@@ -40,8 +40,6 @@ class HttpRequestComponent : public Component {
void set_method(const char *method) { this->method_ = method; }
void set_useragent(const char *useragent) { this->useragent_ = useragent; }
void set_timeout(uint16_t timeout) { this->timeout_ = timeout; }
void set_follow_redirects(bool follow_redirects) { this->follow_redirects_ = follow_redirects; }
void set_redirect_limit(uint16_t limit) { this->redirect_limit_ = limit; }
void set_body(const std::string &body) { this->body_ = body; }
void set_headers(std::list<Header> headers) { this->headers_ = std::move(headers); }
void send(const std::vector<HttpRequestResponseTrigger *> &response_triggers);
@@ -55,8 +53,6 @@ class HttpRequestComponent : public Component {
const char *method_;
const char *useragent_{nullptr};
bool secure_;
bool follow_redirects_;
uint16_t redirect_limit_;
uint16_t timeout_{5000};
std::string body_;
std::list<Header> headers_;

View File

@@ -16,11 +16,10 @@ void ArduinoI2CBus::setup() {
#ifdef USE_ESP32
static uint8_t next_bus_num = 0;
if (next_bus_num == 0) {
if (next_bus_num == 0)
wire_ = &Wire;
} else {
else
wire_ = new TwoWire(next_bus_num); // NOLINT(cppcoreguidelines-owning-memory)
}
next_bus_num++;
#else
wire_ = &Wire; // NOLINT(cppcoreguidelines-prefer-member-initializer)
@@ -56,11 +55,10 @@ void ArduinoI2CBus::dump_config() {
ESP_LOGI(TAG, "Found no i2c devices!");
} else {
for (const auto &s : scan_results_) {
if (s.second) {
if (s.second)
ESP_LOGI(TAG, "Found i2c device at address 0x%02X", s.first);
} else {
else
ESP_LOGE(TAG, "Unknown error at address 0x%02X", s.first);
}
}
}
}

View File

@@ -65,11 +65,10 @@ void IDFI2CBus::dump_config() {
ESP_LOGI(TAG, "Found no i2c devices!");
} else {
for (const auto &s : scan_results_) {
if (s.second) {
if (s.second)
ESP_LOGI(TAG, "Found i2c device at address 0x%02X", s.first);
} else {
else
ESP_LOGE(TAG, "Unknown error at address 0x%02X", s.first);
}
}
}
}

View File

@@ -24,7 +24,6 @@ IMAGE_TYPE = {
"BINARY": ImageType.IMAGE_TYPE_BINARY,
"GRAYSCALE": ImageType.IMAGE_TYPE_GRAYSCALE,
"RGB24": ImageType.IMAGE_TYPE_RGB24,
"TRANSPARENT_BINARY": ImageType.IMAGE_TYPE_TRANSPARENT_BINARY,
}
Image_ = display.display_ns.class_("Image")
@@ -100,17 +99,6 @@ async def to_code(config):
pos = x + y * width8
data[pos // 8] |= 0x80 >> (pos % 8)
elif config[CONF_TYPE] == "TRANSPARENT_BINARY":
image = image.convert("RGBA")
width8 = ((width + 7) // 8) * 8
data = [0 for _ in range(height * width8 // 8)]
for y in range(height):
for x in range(width):
if not image.getpixel((x, y))[3]:
continue
pos = x + y * width8
data[pos // 8] |= 0x80 >> (pos % 8)
rhs = [HexInt(x) for x in data]
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
cg.new_Pvariable(

View File

@@ -30,4 +30,4 @@ FINAL_VALIDATE_SCHEMA = validate_logger_baud_rate
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
cg.add_library("esphome/Improv", "1.2.0")
cg.add_library("esphome/Improv", "1.0.0")

View File

@@ -24,8 +24,6 @@ void ImprovSerialComponent::setup() {
if (wifi::global_wifi_component->has_sta()) {
this->state_ = improv::STATE_PROVISIONED;
} else {
wifi::global_wifi_component->start_scanning();
}
}
@@ -97,7 +95,7 @@ std::vector<uint8_t> ImprovSerialComponent::build_rpc_settings_response_(improv:
std::vector<std::string> urls;
#ifdef USE_WEBSERVER
auto ip = wifi::global_wifi_component->wifi_sta_ip();
std::string webserver_url = "http://" + ip.str() + ":" + to_string(USE_WEBSERVER_PORT);
std::string webserver_url = "http://" + ip.str() + ":" + to_string(WEBSERVER_PORT);
urls.push_back(webserver_url);
#endif
std::vector<uint8_t> data = improv::build_rpc_response(command, urls, false);
@@ -113,15 +111,58 @@ std::vector<uint8_t> ImprovSerialComponent::build_version_info_() {
bool ImprovSerialComponent::parse_improv_serial_byte_(uint8_t byte) {
size_t at = this->rx_buffer_.size();
this->rx_buffer_.push_back(byte);
ESP_LOGV(TAG, "Improv Serial byte: 0x%02X", byte);
ESP_LOGD(TAG, "Improv Serial byte: 0x%02X", byte);
const uint8_t *raw = &this->rx_buffer_[0];
if (at == 0)
return byte == 'I';
if (at == 1)
return byte == 'M';
if (at == 2)
return byte == 'P';
if (at == 3)
return byte == 'R';
if (at == 4)
return byte == 'O';
if (at == 5)
return byte == 'V';
return improv::parse_improv_serial_byte(
at, byte, raw, [this](improv::ImprovCommand command) -> bool { return this->parse_improv_payload_(command); },
[this](improv::Error error) -> void {
ESP_LOGW(TAG, "Error decoding Improv payload");
this->set_error_(error);
});
if (at == 6)
return byte == IMPROV_SERIAL_VERSION;
if (at == 7)
return true;
uint8_t type = raw[7];
if (at == 8)
return true;
uint8_t data_len = raw[8];
if (at < 8 + data_len)
return true;
if (at == 8 + data_len)
return true;
if (at == 8 + data_len + 1) {
uint8_t checksum = 0x00;
for (size_t i = 0; i < at; i++)
checksum += raw[i];
if (checksum != byte) {
ESP_LOGW(TAG, "Error decoding Improv payload");
this->set_error_(improv::ERROR_INVALID_RPC);
return false;
}
if (type == TYPE_RPC) {
this->set_error_(improv::ERROR_NONE);
auto command = improv::parse_improv_data(&raw[9], data_len, false);
return this->parse_improv_payload_(command);
}
}
// If we got here then the command coming is is improv, but not an RPC command
return false;
}
bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command) {
@@ -154,27 +195,6 @@ bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command
this->send_response_(info);
return true;
}
case improv::GET_WIFI_NETWORKS: {
std::vector<std::string> networks;
auto results = wifi::global_wifi_component->get_scan_result();
for (auto &scan : results) {
if (scan.get_is_hidden())
continue;
const std::string &ssid = scan.get_ssid();
if (std::find(networks.begin(), networks.end(), ssid) != networks.end())
continue;
// Send each ssid separately to avoid overflowing the buffer
std::vector<uint8_t> data = improv::build_rpc_response(
improv::GET_WIFI_NETWORKS, {ssid, str_sprintf("%d", scan.get_rssi()), YESNO(scan.get_with_auth())}, false);
this->send_response_(data);
networks.push_back(ssid);
}
// Send empty response to signify the end of the list.
std::vector<uint8_t> data =
improv::build_rpc_response(improv::GET_WIFI_NETWORKS, std::vector<std::string>{}, false);
this->send_response_(data);
return true;
}
default: {
ESP_LOGW(TAG, "Unknown Improv payload");
this->set_error_(improv::ERROR_UNKNOWN_RPC);

View File

@@ -32,7 +32,7 @@ class ImprovSerialComponent : public Component {
void loop() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
float get_setup_priority() const override { return setup_priority::HARDWARE; }
protected:
bool parse_improv_serial_byte_(uint8_t byte);

View File

@@ -548,15 +548,14 @@ void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) {
eink_on_();
uint8_t data = 0;
if (c == 0) { // White
if (c == 0) // White
data = 0b10101010;
} else if (c == 1) { // Black
else if (c == 1) // Black
data = 0b01010101;
} else if (c == 2) { // Discharge
else if (c == 2) // Discharge
data = 0b00000000;
} else if (c == 3) { // Skip
else if (c == 3) // Skip
data = 0b11111111;
}
uint32_t send = ((data & 0b00000011) << 4) | (((data & 0b00001100) >> 2) << 18) | (((data & 0b00010000) >> 4) << 23) |
(((data & 0b11100000) >> 5) << 25);

View File

@@ -109,20 +109,18 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public
void pins_as_outputs_();
int get_width_internal() override {
if (this->model_ == INKPLATE_6) {
if (this->model_ == INKPLATE_6)
return 800;
} else if (this->model_ == INKPLATE_10) {
else if (this->model_ == INKPLATE_10)
return 1200;
}
return 0;
}
int get_height_internal() override {
if (this->model_ == INKPLATE_6) {
if (this->model_ == INKPLATE_6)
return 600;
} else if (this->model_ == INKPLATE_10) {
else if (this->model_ == INKPLATE_10)
return 825;
}
return 0;
}

View File

@@ -28,7 +28,7 @@ void KalmanCombinatorComponent::add_source(Sensor *sensor, std::function<float(f
}
void KalmanCombinatorComponent::add_source(Sensor *sensor, float stddev) {
this->add_source(sensor, std::function<float(float)>{[stddev](float x) -> float { return stddev; }});
this->add_source(sensor, std::function<float(float)>{[stddev](float) -> float { return stddev; }});
}
void KalmanCombinatorComponent::update_variance_() {

View File

@@ -13,12 +13,12 @@ DEPENDENCIES = ["esp32"]
def calc_max_frequency(bit_depth):
return 80e6 / (2**bit_depth)
return 80e6 / (2 ** bit_depth)
def calc_min_frequency(bit_depth):
max_div_num = ((2**20) - 1) / 256.0
return 80e6 / (max_div_num * (2**bit_depth))
max_div_num = ((2 ** 20) - 1) / 256.0
return 80e6 / (max_div_num * (2 ** bit_depth))
def validate_frequency(value):

View File

@@ -102,24 +102,21 @@ class RandomLightEffect : public LightEffect {
class LambdaLightEffect : public LightEffect {
public:
LambdaLightEffect(const std::string &name, std::function<void(bool initial_run)> f, uint32_t update_interval)
LambdaLightEffect(const std::string &name, std::function<void()> f, uint32_t update_interval)
: LightEffect(name), f_(std::move(f)), update_interval_(update_interval) {}
void start() override { this->initial_run_ = true; }
void apply() override {
const uint32_t now = millis();
if (now - this->last_run_ >= this->update_interval_) {
this->last_run_ = now;
this->f_(this->initial_run_);
this->initial_run_ = false;
this->f_();
}
}
protected:
std::function<void(bool initial_run)> f_;
std::function<void()> f_;
uint32_t update_interval_;
uint32_t last_run_{0};
bool initial_run_;
};
class AutomationLightEffect : public LightEffect {

View File

@@ -141,9 +141,7 @@ def register_addressable_effect(
},
)
async def lambda_effect_to_code(config, effect_id):
lambda_ = await cg.process_lambda(
config[CONF_LAMBDA], [(bool, "initial_run")], return_type=cg.void
)
lambda_ = await cg.process_lambda(config[CONF_LAMBDA], [], return_type=cg.void)
return cg.new_Pvariable(
effect_id, config[CONF_NAME], lambda_, config[CONF_UPDATE_INTERVAL]
)

View File

@@ -98,11 +98,10 @@ void LightCall::perform() {
// EFFECT
auto effect = this->effect_;
const char *effect_s;
if (effect == 0u) {
if (effect == 0u)
effect_s = "None";
} else {
else
effect_s = this->parent_->effects_[*this->effect_ - 1]->get_name().c_str();
}
if (this->publish_) {
ESP_LOGD(TAG, " Effect: '%s'", effect_s);
@@ -446,10 +445,9 @@ std::set<ColorMode> LightCall::get_suitable_color_modes_() {
};
auto key = KEY(has_white, has_ct, has_cwww, has_rgb);
for (auto &item : lookup_table) {
for (auto &item : lookup_table)
if (std::get<0>(item) == key)
return std::get<1>(item);
}
// This happens if there are conflicting flags given.
return {};

View File

@@ -145,11 +145,10 @@ void LightState::publish_state() { this->remote_values_callback_.call(); }
LightOutput *LightState::get_output() const { return this->output_; }
std::string LightState::get_effect_name() {
if (this->active_effect_index_ > 0) {
if (this->active_effect_index_ > 0)
return this->effects_[this->active_effect_index_ - 1]->get_name();
} else {
else
return "None";
}
}
void LightState::add_new_remote_values_callback(std::function<void()> &&send_callback) {
@@ -220,11 +219,10 @@ void LightState::start_effect_(uint32_t effect_index) {
effect->start_internal();
}
LightEffect *LightState::get_active_effect_() {
if (this->active_effect_index_ == 0) {
if (this->active_effect_index_ == 0)
return nullptr;
} else {
else
return this->effects_[this->active_effect_index_ - 1];
}
}
void LightState::stop_effect_() {
auto *effect = this->get_active_effect_();

View File

@@ -143,13 +143,11 @@ void MAX7219Component::dump_config() {
void MAX7219Component::display() {
for (uint8_t i = 0; i < 8; i++) {
this->enable();
for (uint8_t j = 0; j < this->num_chips_; j++) {
if (reverse_) {
for (uint8_t j = 0; j < this->num_chips_; j++)
if (reverse_)
this->send_byte_(8 - i, buffer_[(num_chips_ - j - 1) * 8 + i]);
} else {
else
this->send_byte_(8 - i, buffer_[j * 8 + i]);
}
}
this->disable();
}
}

View File

@@ -253,11 +253,10 @@ void MAX7219Component::send_char(uint8_t chip, uint8_t data) {
void MAX7219Component::send64pixels(uint8_t chip, const uint8_t pixels[8]) {
for (uint8_t col = 0; col < 8; col++) { // RUN THIS LOOP 8 times until column is 7
this->enable(); // start sending by enabling SPI
for (uint8_t i = 0; i < chip; i++) { // send extra NOPs to push the pixels out to extra displays
for (uint8_t i = 0; i < chip; i++) // send extra NOPs to push the pixels out to extra displays
this->send_byte_(MAX7219_REGISTER_NOOP,
MAX7219_REGISTER_NOOP); // run this loop unit the matching chip is reached
}
uint8_t b = 0; // rotate pixels 90 degrees -- set byte to 0
uint8_t b = 0; // rotate pixels 90 degrees -- set byte to 0
if (this->orientation_ == 0) {
for (uint8_t i = 0; i < 8; i++) {
// run this loop 8 times for all the pixels[8] received

View File

@@ -62,11 +62,10 @@ void MCP23016::update_reg_(uint8_t pin, bool pin_value, uint8_t reg_addr) {
this->read_reg_(reg_addr, &reg_value);
}
if (pin_value) {
if (pin_value)
reg_value |= 1 << bit;
} else {
else
reg_value &= ~(1 << bit);
}
this->write_reg_(reg_addr, reg_value);

View File

@@ -67,11 +67,10 @@ void MCP23X08Base::update_reg(uint8_t pin, bool pin_value, uint8_t reg_addr) {
this->read_reg(reg_addr, &reg_value);
}
if (pin_value) {
if (pin_value)
reg_value |= 1 << bit;
} else {
else
reg_value &= ~(1 << bit);
}
this->write_reg(reg_addr, reg_value);

View File

@@ -70,11 +70,10 @@ void MCP23X17Base::update_reg(uint8_t pin, bool pin_value, uint8_t reg_addr) {
this->read_reg(reg_addr, &reg_value);
}
if (pin_value) {
if (pin_value)
reg_value |= 1 << bit;
} else {
else
reg_value &= ~(1 << bit);
}
this->write_reg(reg_addr, reg_value);

View File

@@ -6,7 +6,6 @@
namespace esphome {
namespace md5 {
#ifdef USE_ARDUINO
void MD5Digest::init() {
memset(this->digest_, 0, 16);
MD5Init(&this->ctx_);
@@ -15,18 +14,6 @@ void MD5Digest::init() {
void MD5Digest::add(const uint8_t *data, size_t len) { MD5Update(&this->ctx_, data, len); }
void MD5Digest::calculate() { MD5Final(this->digest_, &this->ctx_); }
#endif // USE_ARDUINO
#ifdef USE_ESP_IDF
void MD5Digest::init() {
memset(this->digest_, 0, 16);
esp_rom_md5_init(&this->ctx_);
}
void MD5Digest::add(const uint8_t *data, size_t len) { esp_rom_md5_update(&this->ctx_, data, len); }
void MD5Digest::calculate() { esp_rom_md5_final(this->digest_, &this->ctx_); }
#endif // USE_ESP_IDF
void MD5Digest::get_bytes(uint8_t *output) { memcpy(output, this->digest_, 16); }

View File

@@ -3,8 +3,8 @@
#include "esphome/core/defines.h"
#ifdef USE_ESP_IDF
#include "esp_rom_md5.h"
#define MD5_CTX_TYPE md5_context_t
#include "esp32/rom/md5_hash.h"
#define MD5_CTX_TYPE MD5Context
#endif
#if defined(USE_ARDUINO) && defined(USE_ESP32)

View File

@@ -16,8 +16,8 @@ namespace mdns {
static const char *const TAG = "mdns";
#ifndef USE_WEBSERVER_PORT
#define USE_WEBSERVER_PORT 80 // NOLINT
#ifndef WEBSERVER_PORT
#define WEBSERVER_PORT 80 // NOLINT
#endif
void MDNSComponent::compile_records_() {
@@ -63,7 +63,7 @@ void MDNSComponent::compile_records_() {
MDNSService service{};
service.service_type = "_prometheus-http";
service.proto = "_tcp";
service.port = USE_WEBSERVER_PORT;
service.port = WEBSERVER_PORT;
this->services_.push_back(service);
}
#endif
@@ -74,7 +74,7 @@ void MDNSComponent::compile_records_() {
MDNSService service{};
service.service_type = "_http";
service.proto = "_tcp";
service.port = USE_WEBSERVER_PORT;
service.port = WEBSERVER_PORT;
service.txt_records.push_back({"version", ESPHOME_VERSION});
this->services_.push_back(service);
}

View File

@@ -20,11 +20,11 @@ void MDNSComponent::setup() {
// part of the wire protocol to have an underscore, and for example ESP-IDF
// expects the underscore to be there, the ESP8266 implementation always adds
// the underscore itself.
auto *proto = service.proto.c_str();
auto proto = service.proto.c_str();
while (*proto == '_') {
proto++;
}
auto *service_type = service.service_type.c_str();
auto service_type = service.service_type.c_str();
while (*service_type == '_') {
service_type++;
}

View File

@@ -59,16 +59,14 @@ void AirConditioner::control(const ClimateCall &call) {
ctrl.swingMode = Converters::to_midea_swing_mode(call.get_swing_mode().value());
if (call.get_mode().has_value())
ctrl.mode = Converters::to_midea_mode(call.get_mode().value());
if (call.get_preset().has_value()) {
if (call.get_preset().has_value())
ctrl.preset = Converters::to_midea_preset(call.get_preset().value());
} else if (call.get_custom_preset().has_value()) {
else if (call.get_custom_preset().has_value())
ctrl.preset = Converters::to_midea_preset(call.get_custom_preset().value());
}
if (call.get_fan_mode().has_value()) {
if (call.get_fan_mode().has_value())
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_fan_mode().value());
} else if (call.get_custom_fan_mode().has_value()) {
else if (call.get_custom_fan_mode().has_value())
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode().value());
}
this->base_.control(ctrl);
}

View File

@@ -172,11 +172,10 @@ bool MideaIR::on_midea_(const MideaData &data) {
this->target_temperature = status.get_temp();
this->mode = status.get_mode();
this->fan_mode = status.get_fan_mode();
if (status.get_sleep_preset()) {
if (status.get_sleep_preset())
this->preset = climate::CLIMATE_PRESET_SLEEP;
} else if (this->preset == climate::CLIMATE_PRESET_SLEEP) {
else if (this->preset == climate::CLIMATE_PRESET_SLEEP)
this->preset = climate::CLIMATE_PRESET_NONE;
}
this->publish_state();
return true;
}

View File

@@ -54,7 +54,7 @@ void MitsubishiClimate::transmit_state() {
}
auto transmit = this->transmitter_->transmit();
auto *data = transmit.get_data();
auto data = transmit.get_data();
data->set_carrier_frequency(38000);
// repeat twice
@@ -63,13 +63,12 @@ void MitsubishiClimate::transmit_state() {
data->mark(MITSUBISHI_HEADER_MARK);
data->space(MITSUBISHI_HEADER_SPACE);
// Data
for (uint8_t i : remote_state) {
for (uint8_t i : remote_state)
for (uint8_t j = 0; j < 8; j++) {
data->mark(MITSUBISHI_BIT_MARK);
bool bit = i & (1 << j);
data->space(bit ? MITSUBISHI_ONE_SPACE : MITSUBISHI_ZERO_SPACE);
}
}
// Footer
if (r == 0) {
data->mark(MITSUBISHI_BIT_MARK);

View File

@@ -10,7 +10,8 @@ namespace modbus_controller {
class ModbusBinarySensor : public Component, public binary_sensor::BinarySensor, public SensorItem {
public:
ModbusBinarySensor(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint32_t bitmask,
uint8_t skip_updates, bool force_new_range) {
uint8_t skip_updates, bool force_new_range)
: Component(), binary_sensor::BinarySensor() {
this->register_type = register_type;
this->start_address = start_address;
this->offset = offset;
@@ -19,11 +20,10 @@ class ModbusBinarySensor : public Component, public binary_sensor::BinarySensor,
this->skip_updates = skip_updates;
this->force_new_range = force_new_range;
if (register_type == ModbusRegisterType::COIL || register_type == ModbusRegisterType::DISCRETE_INPUT) {
if (register_type == ModbusRegisterType::COIL || register_type == ModbusRegisterType::DISCRETE_INPUT)
this->register_count = offset + 1;
} else {
else
this->register_count = 1;
}
}
void parse_and_publish(const std::vector<uint8_t> &data) override;

View File

@@ -99,7 +99,7 @@ void ModbusController::on_register_data(ModbusRegisterType register_type, uint16
// loop through all sensors with the same start address
auto sensors = find_sensors_(register_type, start_address);
for (auto *sensor : sensors) {
for (auto sensor : sensors) {
sensor->parse_and_publish(data);
}
}
@@ -440,7 +440,7 @@ ModbusCommandItem ModbusCommandItem::create_custom_command(
cmd.modbusdevice = modbusdevice;
cmd.function_code = ModbusFunctionCode::CUSTOM;
if (handler == nullptr) {
cmd.on_data_func = [](ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data) {
cmd.on_data_func = [](ModbusRegisterType, uint16_t, const std::vector<uint8_t> &data) {
ESP_LOGI(TAG, "Custom Command sent");
};
} else {

View File

@@ -230,11 +230,10 @@ class SensorItem {
void set_custom_data(const std::vector<uint8_t> &data) { custom_data = data; }
size_t virtual get_register_size() const {
if (register_type == ModbusRegisterType::COIL || register_type == ModbusRegisterType::DISCRETE_INPUT) {
if (register_type == ModbusRegisterType::COIL || register_type == ModbusRegisterType::DISCRETE_INPUT)
return 1;
} else { // if CONF_RESPONSE_BYTES is used override the default
else // if CONF_RESPONSE_BYTES is used override the default
return response_bytes > 0 ? response_bytes : register_count * 2;
}
}
// Override register size for modbus devices not using 1 register for one dword
void set_register_size(uint8_t register_size) { response_bytes = register_size; }
@@ -394,7 +393,7 @@ class ModbusCommandItem {
class ModbusController : public PollingComponent, public modbus::ModbusDevice {
public:
ModbusController(uint16_t throttle = 0) : command_throttle_(throttle){};
ModbusController(uint16_t throttle = 0) : modbus::ModbusDevice(), command_throttle_(throttle){};
void dump_config() override;
void loop() override;
void setup() override;

View File

@@ -58,7 +58,8 @@ def validate_modbus_number(config):
CONFIG_SCHEMA = cv.All(
number.NUMBER_SCHEMA.extend(ModbusItemBaseSchema).extend(
number.NUMBER_SCHEMA.extend(ModbusItemBaseSchema)
.extend(
{
cv.GenerateID(): cv.declare_id(ModbusNumber),
cv.Optional(CONF_VALUE_TYPE, default="U_WORD"): cv.enum(SENSOR_VALUE_TYPE),
@@ -71,7 +72,8 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_MULTIPLY, default=1.0): cv.float_,
cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean,
}
),
)
.extend(cv.polling_component_schema("60s")),
validate_min_max,
validate_modbus_number,
)

View File

@@ -57,11 +57,9 @@ void ModbusNumber::control(float value) {
// Create and send the write command
ModbusCommandItem write_cmd;
if (this->register_count == 1 && !this->use_write_multiple_) {
// since offset is in bytes and a register is 16 bits we get the start by adding offset/2
write_cmd =
ModbusCommandItem::create_write_single_command(parent_, this->start_address + this->offset / 2, data[0]);
write_cmd = ModbusCommandItem::create_write_single_command(parent_, this->start_address + this->offset, data[0]);
} else {
write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset / 2,
write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset,
this->register_count, data);
}
// publish new value

View File

@@ -12,7 +12,8 @@ using value_to_data_t = std::function<float>(float);
class ModbusNumber : public number::Number, public Component, public SensorItem {
public:
ModbusNumber(uint16_t start_address, uint8_t offset, uint32_t bitmask, SensorValueType value_type, int register_count,
uint8_t skip_updates, bool force_new_range) {
uint8_t skip_updates, bool force_new_range)
: number::Number(), Component(), SensorItem() {
this->register_type = ModbusRegisterType::HOLDING;
this->start_address = start_address;
this->offset = offset;
@@ -26,6 +27,7 @@ class ModbusNumber : public number::Number, public Component, public SensorItem
void dump_config() override;
void parse_and_publish(const std::vector<uint8_t> &data) override;
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void set_update_interval(int) {}
void set_parent(ModbusController *parent) { this->parent_ = parent; }
void set_write_multiply(float factor) { multiply_by_ = factor; }

View File

@@ -9,7 +9,8 @@ namespace modbus_controller {
class ModbusFloatOutput : public output::FloatOutput, public Component, public SensorItem {
public:
ModbusFloatOutput(uint16_t start_address, uint8_t offset, SensorValueType value_type, int register_count) {
ModbusFloatOutput(uint16_t start_address, uint8_t offset, SensorValueType value_type, int register_count)
: output::FloatOutput(), Component() {
this->register_type = ModbusRegisterType::HOLDING;
this->start_address = start_address;
this->offset = offset;
@@ -42,7 +43,7 @@ class ModbusFloatOutput : public output::FloatOutput, public Component, public S
class ModbusBinaryOutput : public output::BinaryOutput, public Component, public SensorItem {
public:
ModbusBinaryOutput(uint16_t start_address, uint8_t offset) {
ModbusBinaryOutput(uint16_t start_address, uint8_t offset) : output::BinaryOutput(), Component() {
this->register_type = ModbusRegisterType::COIL;
this->start_address = start_address;
this->bitmask = bitmask;

View File

@@ -10,7 +10,8 @@ namespace modbus_controller {
class ModbusSensor : public Component, public sensor::Sensor, public SensorItem {
public:
ModbusSensor(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint32_t bitmask,
SensorValueType value_type, int register_count, uint8_t skip_updates, bool force_new_range) {
SensorValueType value_type, int register_count, uint8_t skip_updates, bool force_new_range)
: Component(), sensor::Sensor() {
this->register_type = register_type;
this->start_address = start_address;
this->offset = offset;

View File

@@ -18,7 +18,6 @@ from ..const import (
CONF_FORCE_NEW_RANGE,
CONF_MODBUS_CONTROLLER_ID,
CONF_REGISTER_TYPE,
CONF_SKIP_UPDATES,
CONF_USE_WRITE_MULTIPLE,
CONF_WRITE_LAMBDA,
)
@@ -54,7 +53,6 @@ async def to_code(config):
config[CONF_ADDRESS],
byte_offset,
config[CONF_BITMASK],
config[CONF_SKIP_UPDATES],
config[CONF_FORCE_NEW_RANGE],
)
await cg.register_component(var, config)

View File

@@ -10,13 +10,14 @@ namespace modbus_controller {
class ModbusSwitch : public Component, public switch_::Switch, public SensorItem {
public:
ModbusSwitch(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint32_t bitmask,
uint8_t skip_updates, bool force_new_range) {
bool force_new_range)
: Component(), switch_::Switch() {
this->register_type = register_type;
this->start_address = start_address;
this->offset = offset;
this->bitmask = bitmask;
this->sensor_value_type = SensorValueType::BIT;
this->skip_updates = skip_updates;
this->skip_updates = 0;
this->register_count = 1;
if (register_type == ModbusRegisterType::HOLDING || register_type == ModbusRegisterType::COIL) {
this->start_address += offset;

View File

@@ -12,7 +12,8 @@ enum class RawEncoding { NONE = 0, HEXBYTES = 1, COMMA = 2 };
class ModbusTextSensor : public Component, public text_sensor::TextSensor, public SensorItem {
public:
ModbusTextSensor(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint8_t register_count,
uint16_t response_bytes, RawEncoding encode, uint8_t skip_updates, bool force_new_range) {
uint16_t response_bytes, RawEncoding encode, uint8_t skip_updates, bool force_new_range)
: Component() {
this->register_type = register_type;
this->start_address = start_address;
this->offset = offset;
@@ -35,6 +36,7 @@ class ModbusTextSensor : public Component, public text_sensor::TextSensor, publi
protected:
optional<transform_func_t> transform_func_{nullopt};
protected:
RawEncoding encode_;
};

View File

@@ -11,7 +11,6 @@ from esphome.const import (
CONF_BROKER,
CONF_CLIENT_ID,
CONF_COMMAND_TOPIC,
CONF_COMMAND_RETAIN,
CONF_DISCOVERY,
CONF_DISCOVERY_PREFIX,
CONF_DISCOVERY_RETAIN,
@@ -393,8 +392,6 @@ async def register_mqtt_component(var, config):
cg.add(var.set_custom_state_topic(config[CONF_STATE_TOPIC]))
if CONF_COMMAND_TOPIC in config:
cg.add(var.set_custom_command_topic(config[CONF_COMMAND_TOPIC]))
if CONF_COMMAND_RETAIN in config:
cg.add(var.set_command_retain(config[CONF_COMMAND_RETAIN]))
if CONF_AVAILABILITY in config:
availability = config[CONF_AVAILABILITY]
if not availability:

View File

@@ -23,7 +23,7 @@ void MQTTBinarySensorComponent::dump_config() {
LOG_MQTT_COMPONENT(true, false)
}
MQTTBinarySensorComponent::MQTTBinarySensorComponent(binary_sensor::BinarySensor *binary_sensor)
: binary_sensor_(binary_sensor) {
: MQTTComponent(), binary_sensor_(binary_sensor) {
if (this->binary_sensor_->is_status_binary_sensor()) {
this->set_custom_state_topic(mqtt::global_mqtt_client->get_availability().topic);
}

View File

@@ -13,7 +13,7 @@ static const char *const TAG = "mqtt.button";
using namespace esphome::button;
MQTTButtonComponent::MQTTButtonComponent(button::Button *button) : button_(button) {}
MQTTButtonComponent::MQTTButtonComponent(button::Button *button) : MQTTComponent(), button_(button) {}
void MQTTButtonComponent::setup() {
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {

View File

@@ -373,11 +373,10 @@ void MQTTClientComponent::unsubscribe(const std::string &topic) {
auto it = subscriptions_.begin();
while (it != subscriptions_.end()) {
if (it->topic == topic) {
if (it->topic == topic)
it = subscriptions_.erase(it);
} else {
else
++it;
}
}
}
@@ -485,10 +484,9 @@ void MQTTClientComponent::on_message(const std::string &topic, const std::string
// in an ISR.
this->defer([this, topic, payload]() {
#endif
for (auto &subscription : this->subscriptions_) {
for (auto &subscription : this->subscriptions_)
if (topic_match(topic.c_str(), subscription.topic.c_str()))
subscription.callback(topic, payload);
}
#ifdef USE_ESP8266
});
#endif

View File

@@ -299,7 +299,7 @@ bool MQTTClimateComponent::publish_state_() {
if (traits.get_supports_fan_modes()) {
std::string payload;
if (this->device_->fan_mode.has_value()) {
if (this->device_->fan_mode.has_value())
switch (this->device_->fan_mode.value()) {
case CLIMATE_FAN_ON:
payload = "on";
@@ -329,7 +329,6 @@ bool MQTTClimateComponent::publish_state_() {
payload = "diffuse";
break;
}
}
if (this->device_->custom_fan_mode.has_value())
payload = this->device_->custom_fan_mode.value();
if (!this->publish(this->get_fan_mode_state_topic(), payload))

View File

@@ -27,13 +27,13 @@ std::string MQTTComponent::get_default_topic_for_(const std::string &suffix) con
"/" + suffix;
}
std::string MQTTComponent::get_state_topic_() const {
const std::string MQTTComponent::get_state_topic_() const {
if (this->custom_state_topic_.empty())
return this->get_default_topic_for_("state");
return this->custom_state_topic_;
}
std::string MQTTComponent::get_command_topic_() const {
const std::string MQTTComponent::get_command_topic_() const {
if (this->custom_command_topic_.empty())
return this->get_default_topic_for_("command");
return this->custom_command_topic_;
@@ -92,8 +92,6 @@ bool MQTTComponent::send_discovery_() {
root[MQTT_STATE_TOPIC] = this->get_state_topic_();
if (config.command_topic)
root[MQTT_COMMAND_TOPIC] = this->get_command_topic_();
if (this->command_retain_)
root[MQTT_COMMAND_RETAIN] = true;
if (this->availability_ == nullptr) {
if (!global_mqtt_client->get_availability().topic.empty()) {
@@ -167,7 +165,6 @@ void MQTTComponent::set_custom_state_topic(const std::string &custom_state_topic
void MQTTComponent::set_custom_command_topic(const std::string &custom_command_topic) {
this->custom_command_topic_ = custom_command_topic;
}
void MQTTComponent::set_command_retain(bool command_retain) { this->command_retain_ = command_retain; }
void MQTTComponent::set_availability(std::string topic, std::string payload_available,
std::string payload_not_available) {

View File

@@ -33,7 +33,7 @@ struct SendDiscoveryConfig {
\
public: \
void set_custom_##name##_##type##_topic(const std::string &topic) { this->custom_##name##_##type##_topic_ = topic; } \
std::string get_##name##_##type##_topic() const { \
const std::string get_##name##_##type##_topic() const { \
if (this->custom_##name##_##type##_topic_.empty()) \
return this->get_default_topic_for_(#name "/" #type); \
return this->custom_##name##_##type##_topic_; \
@@ -91,8 +91,6 @@ class MQTTComponent : public Component {
void set_custom_state_topic(const std::string &custom_state_topic);
/// Set a custom command topic. Set to "" for default behavior.
void set_custom_command_topic(const std::string &custom_command_topic);
/// Set whether command message should be retained.
void set_command_retain(bool command_retain);
/// MQTT_COMPONENT setup priority.
float get_setup_priority() const override;
@@ -173,10 +171,10 @@ class MQTTComponent : public Component {
virtual bool is_disabled_by_default() const;
/// Get the MQTT topic that new states will be shared to.
std::string get_state_topic_() const;
const std::string get_state_topic_() const;
/// Get the MQTT topic for listening to commands.
std::string get_command_topic_() const;
const std::string get_command_topic_() const;
bool is_connected_() const;
@@ -188,9 +186,9 @@ class MQTTComponent : public Component {
/// Generate the Home Assistant MQTT discovery object id by automatically transforming the friendly name.
std::string get_default_object_id_() const;
protected:
std::string custom_state_topic_{};
std::string custom_command_topic_{};
bool command_retain_{false};
bool retain_{true};
bool discovery_enabled_{true};
std::unique_ptr<Availability> availability_;

View File

@@ -45,7 +45,6 @@ constexpr const char *const MQTT_CLEANING_TEMPLATE = "cln_tpl";
constexpr const char *const MQTT_COMMAND_OFF_TEMPLATE = "cmd_off_tpl";
constexpr const char *const MQTT_COMMAND_ON_TEMPLATE = "cmd_on_tpl";
constexpr const char *const MQTT_COMMAND_TOPIC = "cmd_t";
constexpr const char *const MQTT_COMMAND_RETAIN = "ret";
constexpr const char *const MQTT_COMMAND_TEMPLATE = "cmd_tpl";
constexpr const char *const MQTT_CODE_ARM_REQUIRED = "cod_arm_req";
constexpr const char *const MQTT_CODE_DISARM_REQUIRED = "cod_dis_req";
@@ -298,7 +297,6 @@ constexpr const char *const MQTT_CLEANING_TEMPLATE = "cleaning_template";
constexpr const char *const MQTT_COMMAND_OFF_TEMPLATE = "command_off_template";
constexpr const char *const MQTT_COMMAND_ON_TEMPLATE = "command_on_template";
constexpr const char *const MQTT_COMMAND_TOPIC = "command_topic";
constexpr const char *const MQTT_COMMAND_RETAIN = "retain";
constexpr const char *const MQTT_COMMAND_TEMPLATE = "command_template";
constexpr const char *const MQTT_CODE_ARM_REQUIRED = "code_arm_required";
constexpr const char *const MQTT_CODE_DISARM_REQUIRED = "code_disarm_required";

View File

@@ -14,9 +14,9 @@ static const char *const TAG = "mqtt.fan";
using namespace esphome::fan;
MQTTFanComponent::MQTTFanComponent(Fan *state) : state_(state) {}
MQTTFanComponent::MQTTFanComponent(FanState *state) : MQTTComponent(), state_(state) {}
Fan *MQTTFanComponent::get_state() const { return this->state_; }
FanState *MQTTFanComponent::get_state() const { return this->state_; }
std::string MQTTFanComponent::component_type() const { return "fan"; }
const EntityBase *MQTTFanComponent::get_entity() const { return this->state_; }

View File

@@ -13,7 +13,7 @@ namespace mqtt {
class MQTTFanComponent : public mqtt::MQTTComponent {
public:
explicit MQTTFanComponent(fan::Fan *state);
explicit MQTTFanComponent(fan::FanState *state);
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, command)
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, state)
@@ -37,12 +37,12 @@ class MQTTFanComponent : public mqtt::MQTTComponent {
/// 'fan' component type for discovery.
std::string component_type() const override;
fan::Fan *get_state() const;
fan::FanState *get_state() const;
protected:
const EntityBase *get_entity() const override;
fan::Fan *state_;
fan::FanState *state_;
};
} // namespace mqtt

View File

@@ -28,7 +28,7 @@ void MQTTJSONLightComponent::setup() {
this->state_->add_new_remote_values_callback([this, f]() { this->defer("send", f); });
}
MQTTJSONLightComponent::MQTTJSONLightComponent(LightState *state) : state_(state) {}
MQTTJSONLightComponent::MQTTJSONLightComponent(LightState *state) : MQTTComponent(), state_(state) {}
bool MQTTJSONLightComponent::publish_state_() {
return this->publish_json(this->get_state_topic_(),

View File

@@ -13,7 +13,7 @@ static const char *const TAG = "mqtt.number";
using namespace esphome::number;
MQTTNumberComponent::MQTTNumberComponent(Number *number) : number_(number) {}
MQTTNumberComponent::MQTTNumberComponent(Number *number) : MQTTComponent(), number_(number) {}
void MQTTNumberComponent::setup() {
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &state) {

View File

@@ -13,7 +13,7 @@ static const char *const TAG = "mqtt.select";
using namespace esphome::select;
MQTTSelectComponent::MQTTSelectComponent(Select *select) : select_(select) {}
MQTTSelectComponent::MQTTSelectComponent(Select *select) : MQTTComponent(), select_(select) {}
void MQTTSelectComponent::setup() {
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &state) {

View File

@@ -17,7 +17,7 @@ static const char *const TAG = "mqtt.sensor";
using namespace esphome::sensor;
MQTTSensorComponent::MQTTSensorComponent(Sensor *sensor) : sensor_(sensor) {}
MQTTSensorComponent::MQTTSensorComponent(Sensor *sensor) : MQTTComponent(), sensor_(sensor) {}
void MQTTSensorComponent::setup() {
this->sensor_->add_on_state_callback([this](float state) { this->publish_state(state); });

View File

@@ -13,7 +13,7 @@ static const char *const TAG = "mqtt.switch";
using namespace esphome::switch_;
MQTTSwitchComponent::MQTTSwitchComponent(switch_::Switch *a_switch) : switch_(a_switch) {}
MQTTSwitchComponent::MQTTSwitchComponent(switch_::Switch *a_switch) : MQTTComponent(), switch_(a_switch) {}
void MQTTSwitchComponent::setup() {
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {

View File

@@ -11,7 +11,7 @@ static const char *const TAG = "mqtt.text_sensor";
using namespace esphome::text_sensor;
MQTTTextSensor::MQTTTextSensor(TextSensor *sensor) : sensor_(sensor) {}
MQTTTextSensor::MQTTTextSensor(TextSensor *sensor) : MQTTComponent(), sensor_(sensor) {}
void MQTTTextSensor::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
config.command_topic = false;
}

View File

@@ -169,10 +169,6 @@ def _validate_method(value):
CONFIG_SCHEMA = cv.All(
cv.only_with_arduino,
cv.require_framework_version(
esp8266_arduino=cv.Version(2, 4, 0),
esp32_arduino=cv.Version(0, 0, 0),
),
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
{
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(NeoPixelBusLightOutputBase),

View File

@@ -9,6 +9,10 @@
#include "esphome/components/light/light_output.h"
#include "esphome/components/light/addressable_light.h"
#if defined(USE_ESP8266) && ARDUINO_VERSION_CODE < VERSION_CODE(2, 4, 0)
#error The NeoPixelBus library requires at least arduino_version 2.4.x
#endif
#include "NeoPixelBus.h"
namespace esphome {

View File

@@ -1,27 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components.esp32 import add_idf_sdkconfig_option
from esphome.const import (
CONF_ENABLE_IPV6,
)
CODEOWNERS = ["@esphome/core"]
AUTO_LOAD = ["mdns"]
network_ns = cg.esphome_ns.namespace("network")
IPAddress = network_ns.class_("IPAddress")
CONFIG_SCHEMA = cv.Schema(
{
cv.SplitDefault(CONF_ENABLE_IPV6, esp32_idf=False): cv.All(
cv.only_with_esp_idf, cv.boolean
),
}
)
async def to_code(config):
if CONF_ENABLE_IPV6 in config and config[CONF_ENABLE_IPV6]:
add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", True)
add_idf_sdkconfig_option("CONFIG_LWIP_IPV6_AUTOCONFIG", True)

View File

@@ -688,7 +688,7 @@ void Nextion::process_nextion_commands_() {
int index = 0;
int found = -1;
for (auto &nb : this->nextion_queue_) {
auto *component = nb->component;
auto component = nb->component;
if (component->get_queue_type() == NextionQueueType::WAVEFORM_SENSOR) {
size_t buffer_to_send = component->get_wave_buffer().size() < 255 ? component->get_wave_buffer().size()
: 255; // ADDT command can only send 255
@@ -737,10 +737,9 @@ void Nextion::process_nextion_commands_() {
for (size_t i = 0; i < this->nextion_queue_.size(); i++) {
NextionComponentBase *component = this->nextion_queue_[i]->component;
if (this->nextion_queue_[i]->queue_time + this->max_q_age_ms_ < ms) {
if (this->nextion_queue_[i]->queue_time == 0) {
if (this->nextion_queue_[i]->queue_time == 0)
ESP_LOGD(TAG, "Removing old queue type \"%s\" name \"%s\" queue_time 0",
component->get_queue_type_string().c_str(), component->get_variable_name().c_str());
}
if (component->get_variable_name() == "sleep_wake") {
this->is_sleeping_ = false;
@@ -874,9 +873,9 @@ uint16_t Nextion::recv_ret_string_(std::string &response, uint32_t timeout, bool
while ((timeout == 0 && this->available()) || millis() - start <= timeout) {
this->read_byte(&c);
if (c == 0xFF) {
if (c == 0xFF)
nr_of_ff_bytes++;
} else {
else {
nr_of_ff_bytes = 0;
ff_flag = false;
}

View File

@@ -3,7 +3,7 @@
#ifdef USE_NEXTION_TFT_UPLOAD
#include "esphome/core/application.h"
#include "esphome/core/defines.h"
#include "esphome/core/macros.h"
#include "esphome/core/util.h"
#include "esphome/core/log.h"
#include "esphome/components/network/util.h"
@@ -32,12 +32,12 @@ int Nextion::upload_by_chunks_(HTTPClient *http, int range_start) {
range_end = this->tft_size_;
#ifdef USE_ESP8266
#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0)
#if ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0)
http->setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
#elif USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
#elif ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
http->setFollowRedirects(true);
#endif
#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
#if ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
http->setRedirectLimit(3);
#endif
#endif
@@ -148,12 +148,12 @@ void Nextion::upload_tft() {
begin_status = http.begin(this->tft_url_.c_str());
#endif
#ifdef USE_ESP8266
#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0)
#if ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0)
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
#elif USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
#elif ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
http.setFollowRedirects(true);
#endif
#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
#if ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0)
http.setRedirectLimit(3);
#endif
begin_status = http.begin(*this->get_wifi_client_(), this->tft_url_.c_str());

View File

@@ -36,7 +36,7 @@ std::unique_ptr<OTABackend> make_ota_backend() {
}
void OTAComponent::setup() {
server_ = socket::socket_ip(SOCK_STREAM, 0);
server_ = socket::socket(AF_INET, SOCK_STREAM, 0);
if (server_ == nullptr) {
ESP_LOGW(TAG, "Could not create socket.");
this->mark_failed();
@@ -55,14 +55,11 @@ void OTAComponent::setup() {
return;
}
struct sockaddr_storage server;
socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), htons(this->port_));
if (sl == 0) {
ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno);
this->mark_failed();
return;
}
struct sockaddr_in server;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = ESPHOME_INADDR_ANY;
server.sin_port = htons(this->port_);
err = server_->bind((struct sockaddr *) &server, sizeof(server));
if (err != 0) {
@@ -455,11 +452,10 @@ bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_
bool is_manual_safe_mode = this->safe_mode_rtc_value_ == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC;
if (is_manual_safe_mode) {
if (is_manual_safe_mode)
ESP_LOGI(TAG, "Safe mode has been entered manually");
} else {
else
ESP_LOGCONFIG(TAG, "There have been %u suspected unsuccessful boot attempts.", this->safe_mode_rtc_value_);
}
if (this->safe_mode_rtc_value_ >= num_attempts || is_manual_safe_mode) {
this->clean_rtc();

View File

@@ -30,15 +30,6 @@ class BinaryOutput {
void set_power_supply(power_supply::PowerSupply *power_supply) { this->power_.set_parent(power_supply); }
#endif
/// Enable or disable this binary output.
virtual void set_state(bool state) {
if (state) {
this->turn_on();
} else {
this->turn_off();
}
}
/// Enable this binary output.
virtual void turn_on() {
#ifdef USE_POWER_SUPPLY

View File

@@ -1,26 +0,0 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import button, output
from esphome.const import CONF_ID, CONF_OUTPUT, CONF_DURATION
from .. import output_ns
OutputButton = output_ns.class_("OutputButton", button.Button, cg.Component)
CONFIG_SCHEMA = button.BUTTON_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(OutputButton),
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
cv.Required(CONF_DURATION): cv.positive_time_period_milliseconds,
}
).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_duration(config[CONF_DURATION]))
output_ = await cg.get_variable(config[CONF_OUTPUT])
cg.add(var.set_output(output_))
await cg.register_component(var, config)
await button.register_button(var, config)

View File

@@ -1,21 +0,0 @@
#include "output_button.h"
#include "esphome/core/log.h"
namespace esphome {
namespace output {
static const char *const TAG = "output.button";
void OutputButton::dump_config() {
LOG_BUTTON("", "Output Button", this);
ESP_LOGCONFIG(TAG, " Duration: %.1fs", this->duration_ / 1e3f);
}
void OutputButton::press_action() {
this->output_->turn_on();
// Use a named timeout so that it's automatically cancelled if button is pressed again before it's reset
this->set_timeout("reset", this->duration_, [this]() { this->output_->turn_off(); });
}
} // namespace output
} // namespace esphome

View File

@@ -1,25 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/button/button.h"
#include "esphome/components/output/binary_output.h"
namespace esphome {
namespace output {
class OutputButton : public button::Button, public Component {
public:
void dump_config() override;
void set_output(BinaryOutput *output) { output_ = output; }
void set_duration(uint32_t duration) { duration_ = duration; }
protected:
void press_action() override;
output::BinaryOutput *output_;
uint32_t duration_;
};
} // namespace output
} // namespace esphome

View File

@@ -30,11 +30,10 @@ void OutputSwitch::setup() {
break;
}
if (initial_state) {
if (initial_state)
this->turn_on();
} else {
else
this->turn_off();
}
}
void OutputSwitch::write_state(bool state) {
if (state) {

View File

@@ -1,7 +1,6 @@
import re
from pathlib import Path
from esphome.core import EsphomeError
from esphome.config_helpers import merge_config
from esphome import git, yaml_util
from esphome.const import (
@@ -19,6 +18,26 @@ import esphome.config_validation as cv
DOMAIN = CONF_PACKAGES
def _merge_package(full_old, full_new):
def merge(old, new):
# pylint: disable=no-else-return
if isinstance(new, dict):
if not isinstance(old, dict):
return new
res = old.copy()
for k, v in new.items():
res[k] = merge(old[k], v) if k in old else v
return res
elif isinstance(new, list):
if not isinstance(old, list):
return new
return old + new
return new
return merge(full_old, full_new)
def validate_git_package(config: dict):
new_config = config
for key, conf in config.items():
@@ -148,7 +167,7 @@ def do_packages_pass(config: dict):
package_config = _process_base_package(package_config)
if isinstance(package_config, dict):
recursive_package = do_packages_pass(package_config)
config = merge_config(recursive_package, config)
config = _merge_package(recursive_package, config)
del config[CONF_PACKAGES]
return config

View File

@@ -104,6 +104,7 @@ async def to_code(config):
)
light_state = cg.new_Pvariable(conf[CONF_LIGHT_ID], "", wrapper)
await cg.register_component(light_state, conf)
cg.add(cg.App.register_light(light_state))
segments.append(AddressableSegment(light_state, 0, 1, False))
else:

View File

@@ -78,11 +78,10 @@ class PartitionLightOutput : public light::AddressableLight {
int32_t seg_off = index - seg.get_dst_offset();
// offset within the src
int32_t src_off;
if (seg.is_reversed()) {
if (seg.is_reversed())
src_off = seg.get_src_offset() + seg.get_size() - seg_off - 1;
} else {
else
src_off = seg.get_src_offset() + seg_off;
}
auto view = (*seg.get_src())[src_off];
view.raw_set_color_correction(&this->correction_);

View File

@@ -20,13 +20,12 @@ void PIDClimate::setup() {
restore->to_call(this).perform();
} else {
// restore from defaults, change_away handles those for us
if (supports_heat_() && supports_cool_()) {
if (supports_heat_() && supports_cool_())
this->mode = climate::CLIMATE_MODE_HEAT_COOL;
} else if (supports_cool_()) {
else if (supports_cool_())
this->mode = climate::CLIMATE_MODE_COOL;
} else if (supports_heat_()) {
else if (supports_heat_())
this->mode = climate::CLIMATE_MODE_HEAT;
}
this->target_temperature = this->default_target_temperature_;
}
}
@@ -84,15 +83,14 @@ void PIDClimate::write_output_(float value) {
// Update action variable for user feedback what's happening
climate::ClimateAction new_action;
if (this->supports_cool_() && value < 0) {
if (this->supports_cool_() && value < 0)
new_action = climate::CLIMATE_ACTION_COOLING;
} else if (this->supports_heat_() && value > 0) {
else if (this->supports_heat_() && value > 0)
new_action = climate::CLIMATE_ACTION_HEATING;
} else if (this->mode == climate::CLIMATE_MODE_OFF) {
else if (this->mode == climate::CLIMATE_MODE_OFF)
new_action = climate::CLIMATE_ACTION_OFF;
} else {
else
new_action = climate::CLIMATE_ACTION_IDLE;
}
if (new_action != this->action) {
this->action = new_action;

View File

@@ -908,11 +908,10 @@ uint16_t Pipsolar::crc_xmodem_update_(uint16_t crc, uint8_t data) {
int i;
crc = crc ^ ((uint16_t) data << 8);
for (i = 0; i < 8; i++) {
if (crc & 0x8000) {
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021; //(polynomial = 0x1021)
} else {
else
crc <<= 1;
}
}
return crc;
}

View File

@@ -127,7 +127,7 @@ void PrometheusHandler::fan_type_(AsyncResponseStream *stream) {
stream->print(F("#TYPE esphome_fan_speed GAUGE\n"));
stream->print(F("#TYPE esphome_fan_oscillation GAUGE\n"));
}
void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj) {
void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::FanState *obj) {
if (obj->is_internal())
return;
stream->print(F("esphome_fan_failed{id=\""));

View File

@@ -52,7 +52,7 @@ class PrometheusHandler : public AsyncWebHandler, public Component {
/// Return the type for prometheus
void fan_type_(AsyncResponseStream *stream);
/// Return the sensor state as prometheus data point
void fan_row_(AsyncResponseStream *stream, fan::Fan *obj);
void fan_row_(AsyncResponseStream *stream, fan::FanState *obj);
#endif
#ifdef USE_LIGHT

View File

@@ -1,41 +0,0 @@
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import CONF_ID, CONF_VALUE
CONF_SCALE = "scale"
CONF_ECC = "ecc"
CODEOWNERS = ["@wjtje"]
DEPENDENCIES = ["display"]
MULTI_CONF = True
qr_code_ns = cg.esphome_ns.namespace("qr_code")
QRCode = qr_code_ns.class_("QrCode", cg.Component)
qrcodegen_Ecc = cg.esphome_ns.enum("qrcodegen_Ecc")
ECC = {
"LOW": qrcodegen_Ecc.qrcodegen_Ecc_LOW,
"MEDIUM": qrcodegen_Ecc.qrcodegen_Ecc_MEDIUM,
"QUARTILE": qrcodegen_Ecc.qrcodegen_Ecc_QUARTILE,
"HIGH": qrcodegen_Ecc.qrcodegen_Ecc_HIGH,
}
CONFIG_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.declare_id(QRCode),
cv.Required(CONF_VALUE): cv.string,
cv.Optional(CONF_ECC, default="LOW"): cv.enum(ECC, upper=True),
}
)
async def to_code(config):
cg.add_library("wjtje/qr-code-generator-library", "^1.7.0")
var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_value(config[CONF_VALUE]))
cg.add(var.set_ecc(ECC[config[CONF_ECC]]))
await cg.register_component(var, config)
cg.add_define("USE_QR_CODE")

View File

@@ -1,55 +0,0 @@
#include "qr_code.h"
#include "esphome/components/display/display_buffer.h"
#include "esphome/core/color.h"
#include "esphome/core/log.h"
namespace esphome {
namespace qr_code {
static const char *const TAG = "qr_code";
void QrCode::dump_config() {
ESP_LOGCONFIG(TAG, "QR code:");
ESP_LOGCONFIG(TAG, " Value: '%s'", this->value_.c_str());
}
void QrCode::set_value(const std::string &value) {
this->value_ = value;
this->needs_update_ = true;
}
void QrCode::set_ecc(qrcodegen_Ecc ecc) {
this->ecc_ = ecc;
this->needs_update_ = true;
}
void QrCode::generate_qr_code() {
ESP_LOGV(TAG, "Generating QR code...");
uint8_t tempbuffer[qrcodegen_BUFFER_LEN_MAX];
if (!qrcodegen_encodeText(this->value_.c_str(), tempbuffer, this->qr_, this->ecc_, qrcodegen_VERSION_MIN,
qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true)) {
ESP_LOGE(TAG, "Failed to generate QR code");
}
}
void QrCode::draw(display::DisplayBuffer *buff, uint16_t x_offset, uint16_t y_offset, Color color, int scale) {
ESP_LOGV(TAG, "Drawing QR code at (%d, %d)", x_offset, y_offset);
if (this->needs_update_) {
this->generate_qr_code();
this->needs_update_ = false;
}
uint8_t qrcode_width = qrcodegen_getSize(this->qr_);
for (int y = 0; y < qrcode_width * scale; y++) {
for (int x = 0; x < qrcode_width * scale; x++) {
if (qrcodegen_getModule(this->qr_, x / scale, y / scale)) {
buff->draw_pixel_at(x_offset + x, y_offset + y, color);
}
}
}
}
} // namespace qr_code
} // namespace esphome

View File

@@ -1,34 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/color.h"
#include <cstdint>
#include "qrcodegen.h"
namespace esphome {
// forward declare DisplayBuffer
namespace display {
class DisplayBuffer;
} // namespace display
namespace qr_code {
class QrCode : public Component {
public:
void draw(display::DisplayBuffer *buff, uint16_t x_offset, uint16_t y_offset, Color color, int scale);
void dump_config() override;
void set_value(const std::string &value);
void set_ecc(qrcodegen_Ecc ecc);
void generate_qr_code();
protected:
std::string value_;
qrcodegen_Ecc ecc_;
bool needs_update_ = true;
uint8_t qr_[qrcodegen_BUFFER_LEN_MAX];
};
} // namespace qr_code
} // namespace esphome

View File

@@ -139,11 +139,10 @@ void RC522::loop() {
StatusCode status = STATUS_ERROR; // For lint passing. TODO: refactor this
if (awaiting_comm_) {
if (state_ == STATE_SELECT_SERIAL_DONE) {
if (state_ == STATE_SELECT_SERIAL_DONE)
status = await_crc_();
} else {
else
status = await_transceive_();
}
if (status == STATUS_WAITING) {
return;
@@ -211,12 +210,11 @@ void RC522::loop() {
}
case STATE_READ_SERIAL_DONE: {
if (status != STATUS_OK || back_length_ != 3) {
if (status == STATUS_TIMEOUT) {
if (status == STATUS_TIMEOUT)
ESP_LOGV(TAG, "STATE_READ_SERIAL_DONE -> TIMEOUT (no tag present) %d", status);
} else {
else
ESP_LOGW(TAG, "Unexpected response. Read status is %d. Read bytes: %d (%s)", status, back_length_,
format_buffer(buffer_, 9).c_str());
}
state_ = STATE_DONE;
uid_idx_ = 0;
@@ -478,9 +476,9 @@ RC522::StatusCode RC522::await_crc_() {
bool RC522BinarySensor::process(std::vector<uint8_t> &data) {
bool result = true;
if (data.size() != this->uid_.size()) {
if (data.size() != this->uid_.size())
result = false;
} else {
else {
for (size_t i = 0; i < data.size(); i++) {
if (data[i] != this->uid_[i]) {
result = false;

View File

@@ -51,11 +51,10 @@ static bool decode_data(RemoteReceiveData &src, CoolixData &dst) {
for (uint32_t mask = 1 << 7; mask; mask >>= 1) {
if (!src.expect_mark(BIT_MARK_US))
return false;
if (src.expect_space(BIT_ONE_SPACE_US)) {
if (src.expect_space(BIT_ONE_SPACE_US))
data |= mask;
} else if (!src.expect_space(BIT_ZERO_SPACE_US)) {
else if (!src.expect_space(BIT_ZERO_SPACE_US))
return false;
}
}
// Check for inverse byte
for (uint32_t mask = 1 << 7; mask; mask >>= 1) {

View File

@@ -24,20 +24,18 @@ void DishProtocol::encode(RemoteTransmitData *dst, const DishData &data) {
for (uint i = 0; i < 4; i++) {
// COMMAND (function, in MSB)
for (uint8_t mask = 1UL << 5; mask; mask >>= 1) {
if (data.command & mask) {
if (data.command & mask)
dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
} else {
else
dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
}
}
// ADDRESS (unit code, in LSB)
for (uint8_t mask = 1UL; mask < 1UL << 4; mask <<= 1) {
if ((data.address - 1) & mask) {
if ((data.address - 1) & mask)
dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
} else {
else
dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
}
}
// PADDING
for (uint j = 0; j < 6; j++)

View File

@@ -20,11 +20,10 @@ void JVCProtocol::encode(RemoteTransmitData *dst, const JVCData &data) {
dst->item(HEADER_HIGH_US, HEADER_LOW_US);
for (uint32_t mask = 1UL << (NBITS - 1); mask != 0; mask >>= 1) {
if (data.data & mask) {
if (data.data & mask)
dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
} else {
else
dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
}
}
dst->mark(BIT_HIGH_US);

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