1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-07 02:21:51 +00:00

Compare commits

..

152 Commits

Author SHA1 Message Date
Guillermo Ruffino
51ab0f0b78 Bump version to v1.14.5 2020-06-23 22:39:24 -03:00
Otto Winter
bf0cce4ad8 Fix ESP32 interrupt enable/disable switched
Needs to be manually cherry-picked
2020-06-23 22:36:00 -03:00
Otto Winter
60e6366521 Bump version to v1.14.4 2020-06-05 12:56:23 +02:00
Otto Winter
072b2c445c Add ESP8266 core v2.6.2 (#905)
* Add ESP8266 core v2.6.2

* Upstream ESP8266 Wifi fixes

* Replace disable_interrupt with InterruptLock C++ class

* Update code to use InterruptLock

* Lint

* Update dht.cpp

* Improve InterruptLock docs, mark as ICACHE_RAM_ATTR

* Fixes
2020-06-05 12:56:10 +02:00
Otto Winter
219fe41831 Update ESP32 BLE ADV parse to match BLE spec (#904)
* Update ESP32 BLE ADV parse to match BLE spec

* Update xiaomi

* Update ruuvi

* Format

* Update esp32_ble_tracker.cpp

* Fix log

* Format

* Update xiaomi_ble.cpp
2020-06-05 12:55:24 +02:00
Otto Winter
dcc8bb83af Ignore ESP32 Camera unknown framesizes (#901)
Fixes https://github.com/esphome/issues/issues/866
2020-06-05 12:52:05 +02:00
Otto Winter
a8e3521f3c web_server call setup_controller (#899) 2020-06-05 12:52:05 +02:00
Otto Winter
706dc6d116 Fix MQTT logs Int or String expected Python 3 (#898)
Fixes https://github.com/esphome/issues/issues/850
2020-06-05 12:52:04 +02:00
Guillermo Ruffino
84accb6df6 fix climate_ir on receive optional (#897)
* fix climate on receive optional

* add climate tests
2020-06-05 12:52:04 +02:00
warpzone
8421570b18 fix the problem of missing part of advertising packet when activ… (#868)
* fix the problem of missing part of advertising packet when active scan is enabled.

* fix for ci-suggest-changes
2020-06-05 12:52:04 +02:00
Otto Winter
d355543ac9 Merge branch '1.14.4' 2020-06-05 12:42:56 +02:00
Otto Winter
3a597c5aa6 Fix gitignore intellij idea 2020-06-05 12:38:05 +02:00
Otto Winter
c7dddaded4 Upgrade docker base image to 2.1.1 2020-06-05 12:28:37 +02:00
Otto Winter
aae4b2ea5d Upgrade docker base image to 2.1.0 2020-06-05 12:27:26 +02:00
Otto Winter
310e2a0b20 Fix build 2020-06-05 12:25:29 +02:00
Niklas Wagner
0b04d143ac Upgrade dependencies 2020-06-05 12:00:20 +02:00
Otto Winter
53c231a7eb Revert "Atm90e32 pf fix (#841)"
This reverts commit 7842a55c81.
2019-11-17 23:37:00 +01:00
Otto Winter
d44ce82aa1 Bump version to v1.14.3 2019-11-17 23:34:04 +01:00
Otto Winter
a055de48e4 Change ESP8266 default wifi output power (#862)
See also https://github.com/esphome/issues/issues/455
2019-11-17 23:34:01 +01:00
Otto Winter
37b8d665fe Revert ESP32 BLE Tracker defaults (#863)
Fixes https://github.com/esphome/issues/issues/824
Fixes https://github.com/esphome/issues/issues/851
2019-11-17 23:34:01 +01:00
Otto Winter
dd7c8dabb1 Fix MQTT python 3 stringify IPAddress Type (#864)
Fixes https://github.com/esphome/issues/issues/850
2019-11-17 23:34:01 +01:00
Otto Winter
e41a9875e3 Improve WiFi disconnect messages (#857)
* Improve WiFi disconnect messages

* Fix

* Update wifi_component_esp32.cpp
2019-11-17 23:34:01 +01:00
Brandon Davidson
c5c42c4338 Tuya: Fix init sequence and handle wifi test command (#820)
* Handle WiFi test command

Also rename commands to match Tuya protocol docs

* Fix init sequence and product info check

* Fix clang-format suggestions

* Additional changes based on code review

* Fix temp command buffer scope

* Let the interval timer fire the first heatbeat

* Fix init steps; add logging

* Lint

* Remove setup_priority override

* Add delay to dump_config

* Refactor dump sequence

* Fix verbose logging

* Fix lints

* Don't bother suppressing duplicate config dumps

* nolint


Co-authored-by: Otto Winter <otto@otto-winter.com>
2019-11-17 23:34:00 +01:00
Brandon Davidson
531428b8b0 Fix logger uart conflict check (#858)
* Fix logger uart conflict check

* Fix class for check func

* Fix syntax

Hope lint is OK with moving the end of the conditional outside the #IFDEF

* Move end of conditional inside ifdef and remove extra whitespace

* Simplify

clang-format did not like the ifdefs and was reformatting in a way that killed clang-tidy.

Simple solution is to use logger's hw_serial as source of truth

Also simplifies the code - uart doesn't need to know what the logger uart settings mean
2019-11-17 23:34:00 +01:00
Otto Winter
ea8068e001 Switch to 115200 baud upload if 460800 fails (#856)
* Switch to 115200 baud upload if 460800 fails

* Update __main__.py
2019-11-17 23:34:00 +01:00
Mark
7842a55c81 Atm90e32 pf fix (#841)
* correct set_pf_sensor to set_power_factor_senor

* remove junk files added in error

* correct sensors.yaml reference to set_reactive_power

* Fixes
2019-11-17 23:33:56 +01:00
Samuel Sieb
51d39862b1 add position reporting to the template cover (#821)
* add position reporting to the template cover

* remove duplicate import

* use config flag instead


Co-authored-by: Samuel Sieb <samuel@sieb.net>
2019-11-17 23:33:21 +01:00
Otto Winter
bfea6ca79b Mark python 3.5 support deprecated (#849)
* Mark python 3.5 unsupported

Fixes https://github.com/esphome/issues/issues/831

* Update .travis.yml

* Update typing dep
2019-11-17 23:33:20 +01:00
Otto Winter
6297395018 Fix PZEM004T v2 (#846)
Fixes https://github.com/esphome/issues/issues/817
2019-11-17 23:33:20 +01:00
Otto Winter
a5b49dbfa6 Adjust some units (#852)
* Adjust some units

Fixes https://github.com/esphome/issues/issues/843

* Lint
2019-11-17 23:33:12 +01:00
Otto Winter
7c0d777173 Check DHT sensor exists before publishing (#850)
Fixes https://github.com/esphome/issues/issues/841
2019-11-17 23:31:36 +01:00
Otto Winter
74878276fc Web server CORS headers (#840)
* Add CORS header to web server

* Refactor

* Cleanup

See also https://github.com/esphome/issues/issues/806
2019-11-17 23:31:35 +01:00
Otto Winter
226e3b1dad Fix sensor force_update native API (#847)
Fixes https://github.com/esphome/issues/issues/842
2019-11-17 23:31:35 +01:00
Otto Winter
7752794fc5 Fix neopixelbus missing method pins (#848)
Fixes https://github.com/esphome/issues/issues/839
2019-11-17 23:31:35 +01:00
Otto Winter
b3094d6a53 Add missing state attribute (#851)
* Add api missing_state attribute

Fixes https://github.com/esphome/issues/issues/828

Adds a new property for missing state, so that HA can now when a sensor does not have a state yet.

* Update api.proto
2019-11-17 23:31:35 +01:00
Otto Winter
e3640e710f Add wifi output_power setting (#853)
* Add wifi output_power setting

See also:
 - https://github.com/esphome/feature-requests/issues/471#issuecomment-552350467
 - https://github.com/esp8266/Arduino/issues/6366
 - https://github.com/esp8266/Arduino/issues/6471
 - 849f8cf920/code/espurna/config/general.h (L593-L599)
 - https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/network/esp_wifi.html#_CPPv425esp_wifi_set_max_tx_power6int8_t

* Lint
2019-11-17 23:31:35 +01:00
Guillermo Ruffino
2ef64b55c5 fix missing checks of is_playing condition (#844) 2019-11-17 23:31:34 +01:00
Otto Winter
7f6672bb37 Fix calculations for negative sun declination (#839)
Fixes https://github.com/esphome/issues/issues/793

Also adds a clampd function that operates with doubles, not floats
2019-11-17 23:31:34 +01:00
Otto Winter
68a3b31628 Update variable in scheduler (#838)
Fixes https://github.com/esphome/issues/issues/826
2019-11-17 23:31:34 +01:00
Otto Winter
1b35855e68 Update platformio libraries (#837)
* Update platformio libraries

* Lint
2019-11-17 23:31:34 +01:00
Otto Winter
1e1837000d Fix homeassistant.service schema lambda (#833)
* Fix homeassistant.service schema lambda

Fixes https://github.com/esphome/issues/issues/820

* Improve

* Fix
2019-11-17 23:31:34 +01:00
Otto Winter
e2d5257632 Fix ESP32 rotary encoder (#834)
* Fix ESP32 rotary encoder

Fixes https://github.com/esphome/issues/issues/672

* Update rotary_encoder.cpp

* Lint
2019-11-17 23:31:34 +01:00
Otto Winter
387c75793b WiFi AP apply manual ip settings (#836) 2019-11-17 23:31:33 +01:00
Otto Winter
4f3a74d08a ESP8266 remove default opmode check (#835) 2019-11-17 23:31:33 +01:00
Otto Winter
fdbc59a159 Bump version to v1.14.2 2019-11-03 00:20:31 +01:00
Otto Winter
0db37bb55c Fix weird ESP8266 wifi crashes (#831)
* Try fix ESP8266 weird crashes

* Only call disconnect if STA is active
2019-11-03 00:20:25 +01:00
Otto Winter
2ff2750628 Fix stack trace decode for latest platformio (#830) 2019-11-02 21:19:36 +01:00
Otto Winter
eae5c17b87 Bump version to v1.14.1 2019-11-02 21:00:05 +01:00
Otto Winter
a59cde91ad Add servo missing restore option to codegen (#829)
See also https://github.com/esphome/issues/issues/609
2019-11-02 20:59:56 +01:00
Otto Winter
1f243ae37e Remove PCF8574 input_pullup mode and cleanup (#828)
Fixes https://github.com/esphome/issues/issues/755
Closes https://github.com/esphome/esphome/pull/822
Fixes https://github.com/esphome/issues/issues/667
Closes https://github.com/esphome/esphome/pull/808

Co-Authored-By: Amish Vishwakarma <amishv@users.noreply.github.com>
Co-Authored-By: S-Przybylski <s-przybylski@users.noreply.github.com>
2019-11-02 20:59:56 +01:00
Otto Winter
603f82977e Fix update-all input in dashboard (#826)
Fixes https://github.com/esphome/issues/issues/798
2019-11-02 20:59:56 +01:00
Otto Winter
2d70422a6f Move native API enums to new namespace (#825)
Fixes https://github.com/esphome/issues/issues/801
2019-11-02 20:59:55 +01:00
Otto Winter
e2c8b21195 Fix wizard mkdir (#824)
* Fix CLI wizard mkdir_p with empty path

Fixes https://github.com/esphome/issues/issues/796

* Cleanup

* Lint
2019-11-02 20:59:55 +01:00
Alexander Leisentritt
7adaeacd0b refactored xiaomi ble data parsing (#823) 2019-11-02 20:59:55 +01:00
Otto Winter
3aaa92fdff Bump version to v1.14.0 2019-11-01 18:27:24 +01:00
Otto Winter
5efd076c08 Merge branch 'beta' 2019-11-01 18:26:19 +01:00
Otto Winter
5f535e9756 Bump version to v1.14.0b5 2019-10-31 23:46:18 +01:00
Otto Winter
70faeb2fa8 Fix some binary_sensor not having an initial state (#819)
Fixes https://github.com/home-assistant/home-assistant/issues/28384
2019-10-31 23:46:10 +01:00
Otto Winter
469c0db981 Fix fan oscillating (#818)
Fixes https://github.com/esphome/issues/issues/783
2019-10-31 23:46:09 +01:00
Otto Winter
440e428aa4 Scheduler fixes (#813)
* Scheduler fixes

Fixes https://github.com/esphome/issues/issues/789, fixes https://github.com/esphome/issues/issues/788

Also changes to use unique_ptr - this should be much safer than the raw pointers form before (though the scoping rules might cause some issues, but looking closely I didn't find anything)

* Disable debugging

* Format
2019-10-31 23:46:09 +01:00
Otto Winter
dde70c95a4 Allow TimePeriod for time_period_str_unit (#815) 2019-10-31 23:46:09 +01:00
Otto Winter
09d1846261 Print update interval for pulse counter (#816) 2019-10-31 23:46:09 +01:00
Otto Winter
34d26a517d Uppercase ESPHome (#814) 2019-10-31 23:46:09 +01:00
Nikolay Vasilchuk
d24b88271c [Hotfix] Dashboard authentication on Py3 (#812)
* Fix

* Review fix

* Reverted first fix
2019-10-31 23:46:08 +01:00
Antoine GRÉA
f22115792a Add check if middle_text is too short (#811)
* Add check if middle_text is too short

* Use int division as suggested
2019-10-31 23:46:08 +01:00
Otto Winter
82a30558e1 Fix web server transition length truncated (#807)
Fixes https://github.com/esphome/issues/issues/772
2019-10-31 23:46:08 +01:00
Otto Winter
847fe5adca Fix modbus register (#806)
Fixes https://github.com/esphome/feature-requests/issues/49#issuecomment-546555289

Co-Authored-By: tsunglung <tsunglung@users.noreply.github.com>
2019-10-31 23:46:08 +01:00
Otto Winter
775b51c6a1 AS3935 Use normal pin polling for IRQ (#805)
* AS3935 Use normal pin polling for IRQ

See also https://github.com/esphome/feature-requests/issues/452

* Fix tests
2019-10-31 23:46:08 +01:00
Otto Winter
e0ad5a9009 Add Tuya message for no datapoints (#804)
See also https://github.com/esphome/feature-requests/issues/352#issuecomment-546579206
2019-10-31 23:46:07 +01:00
Otto Winter
1bf01a9081 Warn when UART and logger operating on same bus (#803) 2019-10-31 23:46:07 +01:00
Pavel Golovin
6ae59bb43d Fujitsu General climate new component (#677)
* new Fujitsu-General climate component

* Refactor out climate_ir

CC @glmnet

Refactored out climate_ir python files too.
Fixed invalid namespace name for climate_ir.

* Add namespace lint check

* Refactor Fujitsu Climate to climate_ir


Co-authored-by: Otto Winter <otto@otto-winter.com>
2019-10-31 23:46:07 +01:00
Otto Winter
929600d7f7 Fix merge 2019-10-24 22:16:09 +02:00
Otto Winter
163d0c55ab Bump version to v1.14.0b4 2019-10-24 22:02:40 +02:00
Otto Winter
327ccb241e Make file generation saving atomic (#792)
* Make file generation saving atomic

* Lint

* Python 2 Compat

* Fix

* Handle file not found error
2019-10-24 22:02:29 +02:00
Otto Winter
6b3c7b0854 Fix scheduler first execution (#798)
* Fix scheduler first execution not immediately

* Also update sensor filters
2019-10-24 22:02:29 +02:00
Otto Winter
681dcb51da Fix MQTT not showing logs with Python 3 (#797)
* Fix MQTT logging for Python 3

* Also fix captive portal PACKED
2019-10-24 22:02:29 +02:00
Chris Debenham
576d5021fd Add missing include - fixes missing GPIOPin definition (#794) 2019-10-24 22:02:29 +02:00
Otto Winter
6cd76f00ac Implement more dump_configs (#791) 2019-10-24 22:02:29 +02:00
Otto Winter
6f63a62a8d Add lint check for integer constants (#775) 2019-10-24 22:02:23 +02:00
Otto Winter
8867a0fcfb Add additional custom lint checks (#790) 2019-10-24 21:59:24 +02:00
Otto Winter
42b4a166ec Bump version to v1.14.0b3 2019-10-22 23:01:55 +02:00
Otto Winter
c27fd0f01a Fix modbus CRC calculation (#789)
* Fix modbus CRC calculation

Fixes https://github.com/esphome/feature-requests/issues/49#issuecomment-545045776

* Fix
2019-10-22 23:01:51 +02:00
Otto Winter
dcb4a0a81e Add Python 2 deprecation notice (#784)
* Add Python 2 deprecation notice

* Update __main__.py
2019-10-22 23:01:51 +02:00
Nils Schulte
17da9fddc3 web_server_base AUTO_LOAD includes ASYNC_TCP (#788)
* web_server_base AUTO_LOAD includes ASYNC_TCP

fix AUTO_LOAD of web_server_base to include ASYNC_TCP

* Remove from dependencies


Co-authored-by: Otto Winter <otto@otto-winter.com>
2019-10-22 23:01:51 +02:00
Otto Winter
31aa3c55ca Fix ledc can't find bit_depth (#786)
Fixes https://github.com/esphome/issues/issues/759
2019-10-22 23:01:51 +02:00
Otto Winter
eca3685ea0 Update docker base image to 2.0.1 (#785) 2019-10-22 23:01:50 +02:00
Otto Winter
bd216c5c63 Add sensor force_update option (#783)
* Add sensor force_update option

* Add test
2019-10-22 23:01:50 +02:00
amishv
31ff76427c Implementation of LCD Clear (#781)
* Implementation of LCD Clear

* Implementation of LCD Clear

* Implementation of LCD Clear

* Implementation of LCD Clear
2019-10-22 23:01:50 +02:00
Otto Winter
1ca241615d Bump version to v1.13.6 2019-06-14 12:55:23 +02:00
Otto Winter
b8aa84002a Re-add CustomMQTTDevice class (#640)
* Re-add CustomMQTTDevice class

Fixes https://github.com/esphome/issues/issues/427

* Fix
2019-06-14 12:55:20 +02:00
Otto Winter
10cc0b1d5b Fix remote_receiver raw binary sensor (#639)
* Fix remote_receiver raw binary sensor

Fixes https://github.com/esphome/issues/issues/439

* Lint
2019-06-14 12:55:19 +02:00
Otto Winter
11d9c203c1 Fix version.h file (#630)
* Fix version.h file

* Lint
2019-06-14 12:55:19 +02:00
Otto Winter
c9ab454c3c Fix globals.set (#635)
* Fix globals.set

* Update __init__.py
2019-06-14 12:55:19 +02:00
Otto Winter
4a55692885 Fix russia timezone detection (#637)
Fixes https://github.com/esphome/issues/issues/378#issuecomment-500219634
2019-06-14 12:55:19 +02:00
Otto Winter
88c129e705 Fix ESP32 RCSwitch Dump Stack Smash Protection (#636)
Fixes https://github.com/esphome/issues/issues/366
2019-06-14 12:55:19 +02:00
Otto Winter
80b48f01fb Fix esp8266_restore_from_flash (#638)
Fixes https://github.com/esphome/issues/issues/424
2019-06-14 12:36:30 +02:00
Otto Winter
642bc91a76 Update esp32_ble_tracker.cpp 2019-06-08 17:06:29 +02:00
Otto Winter
d69926ee56 Bump version to v1.13.5 2019-06-08 16:49:04 +02:00
Otto Winter
4758403d44 Work around ESP32 core WiFi Bug (#627)
* Work around ESP32 WiFi Bug

* Lint
2019-06-08 16:49:00 +02:00
Otto Winter
4b0ec5c28a Work around ESP32 BLE issue (#626) 2019-06-08 16:49:00 +02:00
Otto Winter
4b2a9e5e49 Fix status binary sensor for MQTT (#628)
Fixes https://github.com/esphome/issues/issues/417
2019-06-08 16:48:59 +02:00
Otto Winter
1449c51d49 Update base image to 1.8.3 (#625) 2019-06-08 16:48:59 +02:00
Otto Winter
a451705e0b Fix sun default elevation (#620) 2019-06-08 16:48:58 +02:00
Otto Winter
2e6db39173 Fix integration sensor, add test (#619)
* Fix integration sensor, add test

* Fix

* Fix
2019-06-08 16:48:58 +02:00
Otto Winter
373f75253c Update docker base image to 1.8.0 (#618) 2019-06-08 16:48:58 +02:00
Otto Winter
724842084e Make ForCondition a component (#616)
Fixes https://github.com/esphome/issues/issues/396
2019-06-08 16:48:57 +02:00
Otto Winter
8f3635b167 Fix remote_receiver always shows sony (#617)
Fixes https://github.com/esphome/issues/issues/383#issuecomment-498370572
2019-06-08 16:48:57 +02:00
Otto Winter
11605a36f7 Fix Hass.io addon SSL (#613)
Fixes https://github.com/esphome/issues/issues/404
2019-06-08 16:48:56 +02:00
Otto Winter
533f81d625 Template Cover don't auto-set current_operation (#612)
Fixes https://github.com/esphome/issues/issues/408
2019-06-08 16:48:56 +02:00
Otto Winter
aacb9e44e8 DHT22 ignore invalid values (#614)
Fixes https://github.com/esphome/issues/issues/397
2019-06-08 16:48:55 +02:00
Peter Tatrai
c6e3f1bca6 Fix ForCondition time duration check (#610)
According documentation ForCondition should evaluate to true if a nested condition is true for at least the specified time duration and not the less.
2019-06-08 16:48:55 +02:00
Otto Winter
a933d4aeb6 Move ESPHome version define (#607)
* Move ESPHome version define

* Lint
2019-06-08 16:48:55 +02:00
Otto Winter
caa5b20791 Bump version to v1.13.4 2019-06-03 15:24:10 +02:00
Otto Winter
e2ad9ed746 ESP8266 connect fixes (#605)
* ESP8266 Connection Fixes

* Update client.py

* Update mqtt_client.cpp

* Update mqtt_client.cpp

* Fix ping

* Async dump config

* Update base image to 1.7.0

* Update helpers.py

* Updates

* Update Dockerfile.lint
2019-06-03 15:23:57 +02:00
Otto Winter
32c0e7c2ae Fix ADS1115 calculation (#606)
Fixes https://github.com/esphome/issues/issues/393
2019-06-03 15:23:56 +02:00
Otto Winter
6c564c7b7f Fix validation infinite loop with empty platform block (#598)
* Fix validation infinite loop with empty platform block

* Update util.py
2019-06-03 15:23:56 +02:00
Otto Winter
c81e3a3be4 Fix hx711 (#602)
* Fix HX711

* Use signed value

* Update hx711.cpp
2019-06-03 15:23:56 +02:00
Otto Winter
6b1b9ef7ec Fix color wipe effect (#599) 2019-06-03 15:23:56 +02:00
Otto Winter
c26a8b8718 Allow old remote_transmitter repeat schema (#601)
Fixes https://github.com/esphome/issues/issues/389
2019-06-03 15:23:56 +02:00
Otto Winter
4a89a475bd Add better esphomeyaml migration path (#600)
Fixes https://github.com/esphome/issues/issues/387
2019-06-03 15:23:55 +02:00
Otto Winter
8cf15c7f5c Bump version to v1.13.3 2019-06-01 22:02:10 +02:00
Otto Winter
adc76ca1b8 Fix dashboard for Py3 installs (#596)
Fixes https://github.com/esphome/issues/issues/368
2019-06-01 22:02:05 +02:00
Otto Winter
8f8892440c Fix medium fan speed (#595) 2019-06-01 22:02:04 +02:00
Otto Winter
570843150d Fix flicker light effect turning itself off (#594)
Fixes https://github.com/esphome/issues/issues/382
2019-06-01 22:02:04 +02:00
Otto Winter
f3fc9e4142 Fix remote_receiver binary_sensor (#592)
Fixes https://github.com/esphome/issues/issues/369
2019-06-01 22:02:04 +02:00
Otto Winter
075fcb77a8 Fix timezone detection (#586)
* Fix timezone detection

* Update __init__.py
2019-06-01 22:02:04 +02:00
Otto Winter
e5899ff717 Fix scripts circular dependency (#591)
Fixes https://github.com/esphome/issues/issues/370
2019-06-01 22:02:04 +02:00
Otto Winter
2fb3970027 Fix addressable effects (#590) 2019-06-01 22:02:03 +02:00
Marc-Antoine Courteau
1a4efa1b8c List the correct boards when building for ESP32 (#589)
* List the ESP32 boards for ESP32 builds.

* Sort the list of valid boards.
2019-06-01 22:02:03 +02:00
Otto Winter
72f656ffef Bump version to v1.13.2 2019-05-31 16:37:56 +02:00
Otto Winter
b60239d5e5 Fix i2c setup priority (#585)
Fixes https://github.com/esphome/issues/issues/314
2019-05-31 16:37:49 +02:00
Otto Winter
d02e280c3c Fix light partition (#584)
* Fix light partition

Fixes https://github.com/esphome/issues/issues/365

* Lint
2019-05-31 16:37:48 +02:00
Otto Winter
6535b0966e Fix MQTT on_message trigger (#583)
Fixes https://github.com/esphome/issues/issues/363
Fixes https://github.com/esphome/issues/issues/364
2019-05-31 16:37:48 +02:00
Otto Winter
82dbacbee5 Fix travis build (#582) 2019-05-31 16:37:48 +02:00
Otto Winter
2432901974 Fix Rotary Encoder (#580)
Fixes https://github.com/esphome/issues/issues/360
2019-05-31 16:37:48 +02:00
Otto Winter
ebb5d58c14 Fix MQTT client_id changed (#579)
Fixes https://github.com/esphome/issues/issues/323
2019-05-31 16:37:48 +02:00
Otto Winter
605e365405 Fix remote_receiver binary_sensor schema (#578)
Fixes https://github.com/esphome/issues/issues/353#issuecomment-497491863
2019-05-31 16:37:47 +02:00
Otto Winter
5ab995d8ca Bump version to v1.13.1 2019-05-30 22:31:56 +02:00
Otto Winter
4248741b11 Fix waveshare 7.5in model (#576)
* Fix waveshare 7.5in model

Fixes https://github.com/esphome/issues/issues/357

* Fix platformio travis errors
2019-05-30 22:31:54 +02:00
Otto Winter
4b8ecc7634 Dashboard work around Hass.io bug (#575)
* Dashboard work around Hass.io bug

Ref https://github.com/home-assistant/hassio/issues/1103

* Lint
2019-05-30 22:31:53 +02:00
Otto Winter
25d04c759c Fix Sun Trigger (#572)
* Fix Sun Trigger

* Fix cwww lights
2019-05-30 22:31:53 +02:00
Otto Winter
b4ec84030e Fix validation TypeError (#574) 2019-05-30 22:31:53 +02:00
Otto Winter
29e8761373 Fix merge 2019-05-30 14:20:06 +02:00
Otto Winter
a04299c59e Bump version to v1.13.0 2019-05-30 14:15:41 +02:00
Otto Winter
d7bf3c51d9 Merge branch 'beta' 2019-05-30 14:15:28 +02:00
Otto Winter
ac0b095941 Bump version to v1.12.2 2019-03-31 13:13:12 +02:00
Otto Winter
cda9bad233 Upgrade docker base image to 1.4.3 (#499) 2019-03-31 13:13:09 +02:00
Otto Winter
41db8a1264 Fix text sensor MQTT settings (#495)
Fixes https://github.com/esphome/issues/issues/170
2019-03-31 13:13:09 +02:00
Otto Winter
e7e785fd60 Fix dashboard wizard unicode (#494)
* Fix dashboard wizard unicode

Fixes https://github.com/esphome/issues/issues/169

* Fix password md5
2019-03-31 13:13:08 +02:00
Otto Winter
300d3a1f46 Upgrade ESPAsyncTCP to 1.2.0 (#497) 2019-03-31 13:13:08 +02:00
Otto Winter
356554c08d ESP8266 SDK 2.3.0 compat (#490) 2019-03-31 13:13:08 +02:00
Guillermo Ruffino
ced28ad006 Better symlink support under Windows (#487)
* Better symlink support under Windows

* Conditional loading of ctypes wintypes module

* Shortening comment line for pylint

* Adding plint bypass for Python 3
2019-03-31 13:13:08 +02:00
161 changed files with 2083 additions and 1070 deletions

1
.gitignore vendored
View File

@@ -114,3 +114,4 @@ config/
tests/build/
tests/.esphome/
/.temp-clang-tidy.cpp
/.idea/

View File

@@ -3,7 +3,7 @@
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375/
BASE_VERSION: '2.0.0'
BASE_VERSION: '2.1.1'
TZ: UTC
stages:
@@ -33,7 +33,7 @@ stages:
- docker info
- docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
script:
- docker run --rm --privileged multiarch/qemu-user-static:4.1.0-1 --reset -p yes
- docker run --rm --privileged multiarch/qemu-user-static:5.0.0-2 --reset -p yes
- TAG="${CI_COMMIT_TAG#v}"
- TAG="${TAG:-${CI_COMMIT_SHA:0:7}}"
- echo "Tag ${TAG}"

View File

@@ -1,6 +1,6 @@
sudo: false
language: python
python: '3.5'
python: '3.6'
install: script/setup
cache:
directories:
@@ -15,8 +15,8 @@ matrix:
- script/ci-custom.py
- flake8 esphome
- pylint esphome
- python: "3.5"
env: TARGET=Test3.5
- python: "3.6"
env: TARGET=Test3.6
script:
- esphome tests/test1.yaml compile
- esphome tests/test2.yaml compile

View File

@@ -1,4 +1,4 @@
ARG BUILD_FROM=esphome/esphome-base-amd64:2.0.0
ARG BUILD_FROM=esphome/esphome-base-amd64:2.1.1
FROM ${BUILD_FROM}
COPY . .

View File

@@ -1,4 +1,4 @@
FROM esphome/esphome-base-amd64:2.0.0
FROM esphome/esphome-base-amd64:2.1.1
RUN \
apt-get update \

View File

@@ -14,7 +14,7 @@ from esphome.const import CONF_BAUD_RATE, CONF_BROKER, CONF_LOGGER, CONF_OTA, \
CONF_PASSWORD, CONF_PORT, CONF_ESPHOME, CONF_PLATFORMIO_OPTIONS
from esphome.core import CORE, EsphomeError, coroutine, coroutine_with_priority
from esphome.helpers import color, indent
from esphome.py_compat import IS_PY2, safe_input
from esphome.py_compat import IS_PY2, safe_input, IS_PY3
from esphome.util import run_external_command, run_external_process, safe_print, list_yaml_files
_LOGGER = logging.getLogger(__name__)
@@ -165,16 +165,27 @@ def compile_program(args, config):
def upload_using_esptool(config, port):
path = CORE.firmware_bin
cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
'--baud', str(config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get('upload_speed', 460800)),
'--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path]
first_baudrate = config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get('upload_speed', 460800)
if os.environ.get('ESPHOME_USE_SUBPROCESS') is None:
import esptool
# pylint: disable=protected-access
return run_external_command(esptool._main, *cmd)
def run_esptool(baud_rate):
cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
'--baud', str(baud_rate),
'--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path]
return run_external_process(*cmd)
if os.environ.get('ESPHOME_USE_SUBPROCESS') is None:
import esptool
# pylint: disable=protected-access
return run_external_command(esptool._main, *cmd)
return run_external_process(*cmd)
rc = run_esptool(first_baudrate)
if rc == 0 or first_baudrate == 115200:
return rc
# Try with 115200 baud rate, with some serial chips the faster baud rates do not work well
_LOGGER.info("Upload with baud rate %s failed. Trying again with baud rate 115200.",
first_baudrate)
return run_esptool(115200)
def upload_program(config, args, host):
@@ -364,14 +375,15 @@ def command_update_all(args):
def print_bar(middle_text):
middle_text = " {} ".format(middle_text)
width = len(click.unstyle(middle_text))
half_line = "=" * ((twidth - width) / 2)
half_line = "=" * ((twidth - width) // 2)
click.echo("%s%s%s" % (half_line, middle_text, half_line))
for f in files:
print("Updating {}".format(color('cyan', f)))
print('-' * twidth)
print()
rc = run_external_process('esphome', '--dashboard', f, 'run', '--no-logs')
rc = run_external_process('esphome', '--dashboard', f, 'run', '--no-logs', '--upload-port',
'OTA')
if rc == 0:
print_bar("[{}] {}".format(color('bold_green', 'SUCCESS'), f))
success[f] = True
@@ -509,6 +521,15 @@ def run_esphome(argv):
_LOGGER.error("Missing configuration parameter, see esphome --help.")
return 1
if IS_PY2:
_LOGGER.warning("You're using ESPHome with python 2. Support for python 2 is deprecated "
"and will be removed in 1.15.0. Please reinstall ESPHome with python 3.6 "
"or higher.")
elif IS_PY3 and sys.version_info < (3, 6, 0):
_LOGGER.warning("You're using ESPHome with python 3.5. Support for python 3.5 is "
"deprecated and will be removed in 1.15.0. Please reinstall ESPHome with "
"python 3.6 or higher.")
if args.command in PRE_CONFIG_ACTIONS:
try:
return PRE_CONFIG_ACTIONS[args.command](args)

View File

@@ -70,14 +70,14 @@ def to_code(config):
cg.add_global(api_ns.using)
KEY_VALUE_SCHEMA = cv.Schema({cv.string: cv.templatable(cv.string)})
KEY_VALUE_SCHEMA = cv.Schema({cv.string: cv.templatable(cv.string_strict)})
HOMEASSISTANT_SERVICE_ACTION_SCHEMA = cv.Schema({
cv.GenerateID(): cv.use_id(APIServer),
cv.Required(CONF_SERVICE): cv.templatable(cv.string),
cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
cv.Optional(CONF_VARIABLES, default={}): KEY_VALUE_SCHEMA,
cv.Optional(CONF_VARIABLES, default={}): cv.Schema({cv.string: cv.returning_lambda}),
})

View File

@@ -216,6 +216,9 @@ message BinarySensorStateResponse {
fixed32 key = 1;
bool state = 2;
// If the binary sensor does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 3;
}
// ==================== COVER ====================
@@ -406,6 +409,7 @@ message ListEntitiesSensorResponse {
string icon = 5;
string unit_of_measurement = 6;
int32 accuracy_decimals = 7;
bool force_update = 8;
}
message SensorStateResponse {
option (id) = 25;
@@ -415,6 +419,9 @@ message SensorStateResponse {
fixed32 key = 1;
float state = 2;
// If the sensor does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 3;
}
// ==================== SWITCH ====================
@@ -471,6 +478,9 @@ message TextSensorStateResponse {
fixed32 key = 1;
string state = 2;
// If the text sensor does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 3;
}
// ==================== SUBSCRIBE LOGS ====================

View File

@@ -163,6 +163,7 @@ bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary
BinarySensorStateResponse resp;
resp.key = binary_sensor->get_object_id_hash();
resp.state = state;
resp.missing_state = !binary_sensor->has_state();
return this->send_binary_sensor_state_response(resp);
}
bool APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
@@ -185,11 +186,12 @@ bool APIConnection::send_cover_state(cover::Cover *cover) {
auto traits = cover->get_traits();
CoverStateResponse resp{};
resp.key = cover->get_object_id_hash();
resp.legacy_state = (cover->position == cover::COVER_OPEN) ? LEGACY_COVER_STATE_OPEN : LEGACY_COVER_STATE_CLOSED;
resp.legacy_state =
(cover->position == cover::COVER_OPEN) ? enums::LEGACY_COVER_STATE_OPEN : enums::LEGACY_COVER_STATE_CLOSED;
resp.position = cover->position;
if (traits.get_supports_tilt())
resp.tilt = cover->tilt;
resp.current_operation = static_cast<EnumCoverOperation>(cover->current_operation);
resp.current_operation = static_cast<enums::CoverOperation>(cover->current_operation);
return this->send_cover_state_response(resp);
}
bool APIConnection::send_cover_info(cover::Cover *cover) {
@@ -213,13 +215,13 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
auto call = cover->make_call();
if (msg.has_legacy_command) {
switch (msg.legacy_command) {
case LEGACY_COVER_COMMAND_OPEN:
case enums::LEGACY_COVER_COMMAND_OPEN:
call.set_command_open();
break;
case LEGACY_COVER_COMMAND_CLOSE:
case enums::LEGACY_COVER_COMMAND_CLOSE:
call.set_command_close();
break;
case LEGACY_COVER_COMMAND_STOP:
case enums::LEGACY_COVER_COMMAND_STOP:
call.set_command_stop();
break;
}
@@ -246,7 +248,7 @@ bool APIConnection::send_fan_state(fan::FanState *fan) {
if (traits.supports_oscillation())
resp.oscillating = fan->oscillating;
if (traits.supports_speed())
resp.speed = static_cast<EnumFanSpeed>(fan->speed);
resp.speed = static_cast<enums::FanSpeed>(fan->speed);
return this->send_fan_state_response(resp);
}
bool APIConnection::send_fan_info(fan::FanState *fan) {
@@ -361,6 +363,7 @@ bool APIConnection::send_sensor_state(sensor::Sensor *sensor, float state) {
SensorStateResponse resp{};
resp.key = sensor->get_object_id_hash();
resp.state = state;
resp.missing_state = !sensor->has_state();
return this->send_sensor_state_response(resp);
}
bool APIConnection::send_sensor_info(sensor::Sensor *sensor) {
@@ -374,6 +377,7 @@ bool APIConnection::send_sensor_info(sensor::Sensor *sensor) {
msg.icon = sensor->get_icon();
msg.unit_of_measurement = sensor->get_unit_of_measurement();
msg.accuracy_decimals = sensor->get_accuracy_decimals();
msg.force_update = sensor->get_force_update();
return this->send_list_entities_sensor_response(msg);
}
#endif
@@ -418,6 +422,7 @@ bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor,
TextSensorStateResponse resp{};
resp.key = text_sensor->get_object_id_hash();
resp.state = std::move(state);
resp.missing_state = !text_sensor->has_state();
return this->send_text_sensor_state_response(resp);
}
bool APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {
@@ -441,8 +446,8 @@ bool APIConnection::send_climate_state(climate::Climate *climate) {
auto traits = climate->get_traits();
ClimateStateResponse resp{};
resp.key = climate->get_object_id_hash();
resp.mode = static_cast<EnumClimateMode>(climate->mode);
resp.action = static_cast<EnumClimateAction>(climate->action);
resp.mode = static_cast<enums::ClimateMode>(climate->mode);
resp.action = static_cast<enums::ClimateAction>(climate->action);
if (traits.get_supports_current_temperature())
resp.current_temperature = climate->current_temperature;
if (traits.get_supports_two_point_target_temperature()) {
@@ -467,7 +472,7 @@ bool APIConnection::send_climate_info(climate::Climate *climate) {
for (auto mode : {climate::CLIMATE_MODE_AUTO, climate::CLIMATE_MODE_OFF, climate::CLIMATE_MODE_COOL,
climate::CLIMATE_MODE_HEAT}) {
if (traits.supports_mode(mode))
msg.supported_modes.push_back(static_cast<EnumClimateMode>(mode));
msg.supported_modes.push_back(static_cast<enums::ClimateMode>(mode));
}
msg.visual_min_temperature = traits.get_visual_min_temperature();
msg.visual_max_temperature = traits.get_visual_max_temperature();

View File

@@ -4,115 +4,115 @@
namespace esphome {
namespace api {
template<> const char *proto_enum_to_string<EnumLegacyCoverState>(EnumLegacyCoverState value) {
template<> const char *proto_enum_to_string<enums::LegacyCoverState>(enums::LegacyCoverState value) {
switch (value) {
case LEGACY_COVER_STATE_OPEN:
case enums::LEGACY_COVER_STATE_OPEN:
return "LEGACY_COVER_STATE_OPEN";
case LEGACY_COVER_STATE_CLOSED:
case enums::LEGACY_COVER_STATE_CLOSED:
return "LEGACY_COVER_STATE_CLOSED";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumCoverOperation>(EnumCoverOperation value) {
template<> const char *proto_enum_to_string<enums::CoverOperation>(enums::CoverOperation value) {
switch (value) {
case COVER_OPERATION_IDLE:
case enums::COVER_OPERATION_IDLE:
return "COVER_OPERATION_IDLE";
case COVER_OPERATION_IS_OPENING:
case enums::COVER_OPERATION_IS_OPENING:
return "COVER_OPERATION_IS_OPENING";
case COVER_OPERATION_IS_CLOSING:
case enums::COVER_OPERATION_IS_CLOSING:
return "COVER_OPERATION_IS_CLOSING";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumLegacyCoverCommand>(EnumLegacyCoverCommand value) {
template<> const char *proto_enum_to_string<enums::LegacyCoverCommand>(enums::LegacyCoverCommand value) {
switch (value) {
case LEGACY_COVER_COMMAND_OPEN:
case enums::LEGACY_COVER_COMMAND_OPEN:
return "LEGACY_COVER_COMMAND_OPEN";
case LEGACY_COVER_COMMAND_CLOSE:
case enums::LEGACY_COVER_COMMAND_CLOSE:
return "LEGACY_COVER_COMMAND_CLOSE";
case LEGACY_COVER_COMMAND_STOP:
case enums::LEGACY_COVER_COMMAND_STOP:
return "LEGACY_COVER_COMMAND_STOP";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumFanSpeed>(EnumFanSpeed value) {
template<> const char *proto_enum_to_string<enums::FanSpeed>(enums::FanSpeed value) {
switch (value) {
case FAN_SPEED_LOW:
case enums::FAN_SPEED_LOW:
return "FAN_SPEED_LOW";
case FAN_SPEED_MEDIUM:
case enums::FAN_SPEED_MEDIUM:
return "FAN_SPEED_MEDIUM";
case FAN_SPEED_HIGH:
case enums::FAN_SPEED_HIGH:
return "FAN_SPEED_HIGH";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumLogLevel>(EnumLogLevel value) {
template<> const char *proto_enum_to_string<enums::LogLevel>(enums::LogLevel value) {
switch (value) {
case LOG_LEVEL_NONE:
case enums::LOG_LEVEL_NONE:
return "LOG_LEVEL_NONE";
case LOG_LEVEL_ERROR:
case enums::LOG_LEVEL_ERROR:
return "LOG_LEVEL_ERROR";
case LOG_LEVEL_WARN:
case enums::LOG_LEVEL_WARN:
return "LOG_LEVEL_WARN";
case LOG_LEVEL_INFO:
case enums::LOG_LEVEL_INFO:
return "LOG_LEVEL_INFO";
case LOG_LEVEL_DEBUG:
case enums::LOG_LEVEL_DEBUG:
return "LOG_LEVEL_DEBUG";
case LOG_LEVEL_VERBOSE:
case enums::LOG_LEVEL_VERBOSE:
return "LOG_LEVEL_VERBOSE";
case LOG_LEVEL_VERY_VERBOSE:
case enums::LOG_LEVEL_VERY_VERBOSE:
return "LOG_LEVEL_VERY_VERBOSE";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumServiceArgType>(EnumServiceArgType value) {
template<> const char *proto_enum_to_string<enums::ServiceArgType>(enums::ServiceArgType value) {
switch (value) {
case SERVICE_ARG_TYPE_BOOL:
case enums::SERVICE_ARG_TYPE_BOOL:
return "SERVICE_ARG_TYPE_BOOL";
case SERVICE_ARG_TYPE_INT:
case enums::SERVICE_ARG_TYPE_INT:
return "SERVICE_ARG_TYPE_INT";
case SERVICE_ARG_TYPE_FLOAT:
case enums::SERVICE_ARG_TYPE_FLOAT:
return "SERVICE_ARG_TYPE_FLOAT";
case SERVICE_ARG_TYPE_STRING:
case enums::SERVICE_ARG_TYPE_STRING:
return "SERVICE_ARG_TYPE_STRING";
case SERVICE_ARG_TYPE_BOOL_ARRAY:
case enums::SERVICE_ARG_TYPE_BOOL_ARRAY:
return "SERVICE_ARG_TYPE_BOOL_ARRAY";
case SERVICE_ARG_TYPE_INT_ARRAY:
case enums::SERVICE_ARG_TYPE_INT_ARRAY:
return "SERVICE_ARG_TYPE_INT_ARRAY";
case SERVICE_ARG_TYPE_FLOAT_ARRAY:
case enums::SERVICE_ARG_TYPE_FLOAT_ARRAY:
return "SERVICE_ARG_TYPE_FLOAT_ARRAY";
case SERVICE_ARG_TYPE_STRING_ARRAY:
case enums::SERVICE_ARG_TYPE_STRING_ARRAY:
return "SERVICE_ARG_TYPE_STRING_ARRAY";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumClimateMode>(EnumClimateMode value) {
template<> const char *proto_enum_to_string<enums::ClimateMode>(enums::ClimateMode value) {
switch (value) {
case CLIMATE_MODE_OFF:
case enums::CLIMATE_MODE_OFF:
return "CLIMATE_MODE_OFF";
case CLIMATE_MODE_AUTO:
case enums::CLIMATE_MODE_AUTO:
return "CLIMATE_MODE_AUTO";
case CLIMATE_MODE_COOL:
case enums::CLIMATE_MODE_COOL:
return "CLIMATE_MODE_COOL";
case CLIMATE_MODE_HEAT:
case enums::CLIMATE_MODE_HEAT:
return "CLIMATE_MODE_HEAT";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<EnumClimateAction>(EnumClimateAction value) {
template<> const char *proto_enum_to_string<enums::ClimateAction>(enums::ClimateAction value) {
switch (value) {
case CLIMATE_ACTION_OFF:
case enums::CLIMATE_ACTION_OFF:
return "CLIMATE_ACTION_OFF";
case CLIMATE_ACTION_COOLING:
case enums::CLIMATE_ACTION_COOLING:
return "CLIMATE_ACTION_COOLING";
case CLIMATE_ACTION_HEATING:
case enums::CLIMATE_ACTION_HEATING:
return "CLIMATE_ACTION_HEATING";
default:
return "UNKNOWN";
@@ -404,6 +404,10 @@ bool BinarySensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt val
this->state = value.as_bool();
return true;
}
case 3: {
this->missing_state = value.as_bool();
return true;
}
default:
return false;
}
@@ -421,6 +425,7 @@ bool BinarySensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value
void BinarySensorStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_bool(2, this->state);
buffer.encode_bool(3, this->missing_state);
}
void BinarySensorStateResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -433,6 +438,10 @@ void BinarySensorStateResponse::dump_to(std::string &out) const {
out.append(" state: ");
out.append(YESNO(this->state));
out.append("\n");
out.append(" missing_state: ");
out.append(YESNO(this->missing_state));
out.append("\n");
out.append("}");
}
bool ListEntitiesCoverResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
@@ -535,11 +544,11 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const {
bool CoverStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 2: {
this->legacy_state = value.as_enum<EnumLegacyCoverState>();
this->legacy_state = value.as_enum<enums::LegacyCoverState>();
return true;
}
case 5: {
this->current_operation = value.as_enum<EnumCoverOperation>();
this->current_operation = value.as_enum<enums::CoverOperation>();
return true;
}
default:
@@ -566,10 +575,10 @@ bool CoverStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
}
void CoverStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_enum<EnumLegacyCoverState>(2, this->legacy_state);
buffer.encode_enum<enums::LegacyCoverState>(2, this->legacy_state);
buffer.encode_float(3, this->position);
buffer.encode_float(4, this->tilt);
buffer.encode_enum<EnumCoverOperation>(5, this->current_operation);
buffer.encode_enum<enums::CoverOperation>(5, this->current_operation);
}
void CoverStateResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -580,7 +589,7 @@ void CoverStateResponse::dump_to(std::string &out) const {
out.append("\n");
out.append(" legacy_state: ");
out.append(proto_enum_to_string<EnumLegacyCoverState>(this->legacy_state));
out.append(proto_enum_to_string<enums::LegacyCoverState>(this->legacy_state));
out.append("\n");
out.append(" position: ");
@@ -594,7 +603,7 @@ void CoverStateResponse::dump_to(std::string &out) const {
out.append("\n");
out.append(" current_operation: ");
out.append(proto_enum_to_string<EnumCoverOperation>(this->current_operation));
out.append(proto_enum_to_string<enums::CoverOperation>(this->current_operation));
out.append("\n");
out.append("}");
}
@@ -605,7 +614,7 @@ bool CoverCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
return true;
}
case 3: {
this->legacy_command = value.as_enum<EnumLegacyCoverCommand>();
this->legacy_command = value.as_enum<enums::LegacyCoverCommand>();
return true;
}
case 4: {
@@ -645,7 +654,7 @@ bool CoverCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
void CoverCommandRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_bool(2, this->has_legacy_command);
buffer.encode_enum<EnumLegacyCoverCommand>(3, this->legacy_command);
buffer.encode_enum<enums::LegacyCoverCommand>(3, this->legacy_command);
buffer.encode_bool(4, this->has_position);
buffer.encode_float(5, this->position);
buffer.encode_bool(6, this->has_tilt);
@@ -665,7 +674,7 @@ void CoverCommandRequest::dump_to(std::string &out) const {
out.append("\n");
out.append(" legacy_command: ");
out.append(proto_enum_to_string<EnumLegacyCoverCommand>(this->legacy_command));
out.append(proto_enum_to_string<enums::LegacyCoverCommand>(this->legacy_command));
out.append("\n");
out.append(" has_position: ");
@@ -781,7 +790,7 @@ bool FanStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
return true;
}
case 4: {
this->speed = value.as_enum<EnumFanSpeed>();
this->speed = value.as_enum<enums::FanSpeed>();
return true;
}
default:
@@ -802,7 +811,7 @@ void FanStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_bool(2, this->state);
buffer.encode_bool(3, this->oscillating);
buffer.encode_enum<EnumFanSpeed>(4, this->speed);
buffer.encode_enum<enums::FanSpeed>(4, this->speed);
}
void FanStateResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -821,7 +830,7 @@ void FanStateResponse::dump_to(std::string &out) const {
out.append("\n");
out.append(" speed: ");
out.append(proto_enum_to_string<EnumFanSpeed>(this->speed));
out.append(proto_enum_to_string<enums::FanSpeed>(this->speed));
out.append("\n");
out.append("}");
}
@@ -840,7 +849,7 @@ bool FanCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
return true;
}
case 5: {
this->speed = value.as_enum<EnumFanSpeed>();
this->speed = value.as_enum<enums::FanSpeed>();
return true;
}
case 6: {
@@ -870,7 +879,7 @@ void FanCommandRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_bool(2, this->has_state);
buffer.encode_bool(3, this->state);
buffer.encode_bool(4, this->has_speed);
buffer.encode_enum<EnumFanSpeed>(5, this->speed);
buffer.encode_enum<enums::FanSpeed>(5, this->speed);
buffer.encode_bool(6, this->has_oscillating);
buffer.encode_bool(7, this->oscillating);
}
@@ -895,7 +904,7 @@ void FanCommandRequest::dump_to(std::string &out) const {
out.append("\n");
out.append(" speed: ");
out.append(proto_enum_to_string<EnumFanSpeed>(this->speed));
out.append(proto_enum_to_string<enums::FanSpeed>(this->speed));
out.append("\n");
out.append(" has_oscillating: ");
@@ -1359,6 +1368,10 @@ bool ListEntitiesSensorResponse::decode_varint(uint32_t field_id, ProtoVarInt va
this->accuracy_decimals = value.as_int32();
return true;
}
case 8: {
this->force_update = value.as_bool();
return true;
}
default:
return false;
}
@@ -1407,6 +1420,7 @@ void ListEntitiesSensorResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(5, this->icon);
buffer.encode_string(6, this->unit_of_measurement);
buffer.encode_int32(7, this->accuracy_decimals);
buffer.encode_bool(8, this->force_update);
}
void ListEntitiesSensorResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -1440,8 +1454,22 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const {
sprintf(buffer, "%d", this->accuracy_decimals);
out.append(buffer);
out.append("\n");
out.append(" force_update: ");
out.append(YESNO(this->force_update));
out.append("\n");
out.append("}");
}
bool SensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 3: {
this->missing_state = value.as_bool();
return true;
}
default:
return false;
}
}
bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
switch (field_id) {
case 1: {
@@ -1459,6 +1487,7 @@ bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
void SensorStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_float(2, this->state);
buffer.encode_bool(3, this->missing_state);
}
void SensorStateResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -1472,6 +1501,10 @@ void SensorStateResponse::dump_to(std::string &out) const {
sprintf(buffer, "%g", this->state);
out.append(buffer);
out.append("\n");
out.append(" missing_state: ");
out.append(YESNO(this->missing_state));
out.append("\n");
out.append("}");
}
bool ListEntitiesSwitchResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
@@ -1691,6 +1724,16 @@ void ListEntitiesTextSensorResponse::dump_to(std::string &out) const {
out.append("\n");
out.append("}");
}
bool TextSensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 3: {
this->missing_state = value.as_bool();
return true;
}
default:
return false;
}
}
bool TextSensorStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) {
case 2: {
@@ -1714,6 +1757,7 @@ bool TextSensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value)
void TextSensorStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_string(2, this->state);
buffer.encode_bool(3, this->missing_state);
}
void TextSensorStateResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -1726,12 +1770,16 @@ void TextSensorStateResponse::dump_to(std::string &out) const {
out.append(" state: ");
out.append("'").append(this->state).append("'");
out.append("\n");
out.append(" missing_state: ");
out.append(YESNO(this->missing_state));
out.append("\n");
out.append("}");
}
bool SubscribeLogsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->level = value.as_enum<EnumLogLevel>();
this->level = value.as_enum<enums::LogLevel>();
return true;
}
case 2: {
@@ -1743,14 +1791,14 @@ bool SubscribeLogsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
}
}
void SubscribeLogsRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_enum<EnumLogLevel>(1, this->level);
buffer.encode_enum<enums::LogLevel>(1, this->level);
buffer.encode_bool(2, this->dump_config);
}
void SubscribeLogsRequest::dump_to(std::string &out) const {
char buffer[64];
out.append("SubscribeLogsRequest {\n");
out.append(" level: ");
out.append(proto_enum_to_string<EnumLogLevel>(this->level));
out.append(proto_enum_to_string<enums::LogLevel>(this->level));
out.append("\n");
out.append(" dump_config: ");
@@ -1761,7 +1809,7 @@ void SubscribeLogsRequest::dump_to(std::string &out) const {
bool SubscribeLogsResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 1: {
this->level = value.as_enum<EnumLogLevel>();
this->level = value.as_enum<enums::LogLevel>();
return true;
}
case 4: {
@@ -1787,7 +1835,7 @@ bool SubscribeLogsResponse::decode_length(uint32_t field_id, ProtoLengthDelimite
}
}
void SubscribeLogsResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_enum<EnumLogLevel>(1, this->level);
buffer.encode_enum<enums::LogLevel>(1, this->level);
buffer.encode_string(2, this->tag);
buffer.encode_string(3, this->message);
buffer.encode_bool(4, this->send_failed);
@@ -1796,7 +1844,7 @@ void SubscribeLogsResponse::dump_to(std::string &out) const {
char buffer[64];
out.append("SubscribeLogsResponse {\n");
out.append(" level: ");
out.append(proto_enum_to_string<EnumLogLevel>(this->level));
out.append(proto_enum_to_string<enums::LogLevel>(this->level));
out.append("\n");
out.append(" tag: ");
@@ -2001,7 +2049,7 @@ void GetTimeResponse::dump_to(std::string &out) const {
bool ListEntitiesServicesArgument::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 2: {
this->type = value.as_enum<EnumServiceArgType>();
this->type = value.as_enum<enums::ServiceArgType>();
return true;
}
default:
@@ -2020,7 +2068,7 @@ bool ListEntitiesServicesArgument::decode_length(uint32_t field_id, ProtoLengthD
}
void ListEntitiesServicesArgument::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->name);
buffer.encode_enum<EnumServiceArgType>(2, this->type);
buffer.encode_enum<enums::ServiceArgType>(2, this->type);
}
void ListEntitiesServicesArgument::dump_to(std::string &out) const {
char buffer[64];
@@ -2030,7 +2078,7 @@ void ListEntitiesServicesArgument::dump_to(std::string &out) const {
out.append("\n");
out.append(" type: ");
out.append(proto_enum_to_string<EnumServiceArgType>(this->type));
out.append(proto_enum_to_string<enums::ServiceArgType>(this->type));
out.append("\n");
out.append("}");
}
@@ -2399,7 +2447,7 @@ bool ListEntitiesClimateResponse::decode_varint(uint32_t field_id, ProtoVarInt v
return true;
}
case 7: {
this->supported_modes.push_back(value.as_enum<EnumClimateMode>());
this->supported_modes.push_back(value.as_enum<enums::ClimateMode>());
return true;
}
case 11: {
@@ -2462,7 +2510,7 @@ void ListEntitiesClimateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_bool(5, this->supports_current_temperature);
buffer.encode_bool(6, this->supports_two_point_target_temperature);
for (auto &it : this->supported_modes) {
buffer.encode_enum<EnumClimateMode>(7, it, true);
buffer.encode_enum<enums::ClimateMode>(7, it, true);
}
buffer.encode_float(8, this->visual_min_temperature);
buffer.encode_float(9, this->visual_max_temperature);
@@ -2500,7 +2548,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const {
for (const auto &it : this->supported_modes) {
out.append(" supported_modes: ");
out.append(proto_enum_to_string<EnumClimateMode>(it));
out.append(proto_enum_to_string<enums::ClimateMode>(it));
out.append("\n");
}
@@ -2531,7 +2579,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const {
bool ClimateStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 2: {
this->mode = value.as_enum<EnumClimateMode>();
this->mode = value.as_enum<enums::ClimateMode>();
return true;
}
case 7: {
@@ -2539,7 +2587,7 @@ bool ClimateStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
return true;
}
case 8: {
this->action = value.as_enum<EnumClimateAction>();
this->action = value.as_enum<enums::ClimateAction>();
return true;
}
default:
@@ -2574,13 +2622,13 @@ bool ClimateStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
}
void ClimateStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_enum<EnumClimateMode>(2, this->mode);
buffer.encode_enum<enums::ClimateMode>(2, this->mode);
buffer.encode_float(3, this->current_temperature);
buffer.encode_float(4, this->target_temperature);
buffer.encode_float(5, this->target_temperature_low);
buffer.encode_float(6, this->target_temperature_high);
buffer.encode_bool(7, this->away);
buffer.encode_enum<EnumClimateAction>(8, this->action);
buffer.encode_enum<enums::ClimateAction>(8, this->action);
}
void ClimateStateResponse::dump_to(std::string &out) const {
char buffer[64];
@@ -2591,7 +2639,7 @@ void ClimateStateResponse::dump_to(std::string &out) const {
out.append("\n");
out.append(" mode: ");
out.append(proto_enum_to_string<EnumClimateMode>(this->mode));
out.append(proto_enum_to_string<enums::ClimateMode>(this->mode));
out.append("\n");
out.append(" current_temperature: ");
@@ -2619,7 +2667,7 @@ void ClimateStateResponse::dump_to(std::string &out) const {
out.append("\n");
out.append(" action: ");
out.append(proto_enum_to_string<EnumClimateAction>(this->action));
out.append(proto_enum_to_string<enums::ClimateAction>(this->action));
out.append("\n");
out.append("}");
}
@@ -2630,7 +2678,7 @@ bool ClimateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value)
return true;
}
case 3: {
this->mode = value.as_enum<EnumClimateMode>();
this->mode = value.as_enum<enums::ClimateMode>();
return true;
}
case 4: {
@@ -2682,7 +2730,7 @@ bool ClimateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
void ClimateCommandRequest::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key);
buffer.encode_bool(2, this->has_mode);
buffer.encode_enum<EnumClimateMode>(3, this->mode);
buffer.encode_enum<enums::ClimateMode>(3, this->mode);
buffer.encode_bool(4, this->has_target_temperature);
buffer.encode_float(5, this->target_temperature);
buffer.encode_bool(6, this->has_target_temperature_low);
@@ -2705,7 +2753,7 @@ void ClimateCommandRequest::dump_to(std::string &out) const {
out.append("\n");
out.append(" mode: ");
out.append(proto_enum_to_string<EnumClimateMode>(this->mode));
out.append(proto_enum_to_string<enums::ClimateMode>(this->mode));
out.append("\n");
out.append(" has_target_temperature: ");

View File

@@ -5,26 +5,28 @@
namespace esphome {
namespace api {
enum EnumLegacyCoverState : uint32_t {
namespace enums {
enum LegacyCoverState : uint32_t {
LEGACY_COVER_STATE_OPEN = 0,
LEGACY_COVER_STATE_CLOSED = 1,
};
enum EnumCoverOperation : uint32_t {
enum CoverOperation : uint32_t {
COVER_OPERATION_IDLE = 0,
COVER_OPERATION_IS_OPENING = 1,
COVER_OPERATION_IS_CLOSING = 2,
};
enum EnumLegacyCoverCommand : uint32_t {
enum LegacyCoverCommand : uint32_t {
LEGACY_COVER_COMMAND_OPEN = 0,
LEGACY_COVER_COMMAND_CLOSE = 1,
LEGACY_COVER_COMMAND_STOP = 2,
};
enum EnumFanSpeed : uint32_t {
enum FanSpeed : uint32_t {
FAN_SPEED_LOW = 0,
FAN_SPEED_MEDIUM = 1,
FAN_SPEED_HIGH = 2,
};
enum EnumLogLevel : uint32_t {
enum LogLevel : uint32_t {
LOG_LEVEL_NONE = 0,
LOG_LEVEL_ERROR = 1,
LOG_LEVEL_WARN = 2,
@@ -33,7 +35,7 @@ enum EnumLogLevel : uint32_t {
LOG_LEVEL_VERBOSE = 5,
LOG_LEVEL_VERY_VERBOSE = 6,
};
enum EnumServiceArgType : uint32_t {
enum ServiceArgType : uint32_t {
SERVICE_ARG_TYPE_BOOL = 0,
SERVICE_ARG_TYPE_INT = 1,
SERVICE_ARG_TYPE_FLOAT = 2,
@@ -43,17 +45,20 @@ enum EnumServiceArgType : uint32_t {
SERVICE_ARG_TYPE_FLOAT_ARRAY = 6,
SERVICE_ARG_TYPE_STRING_ARRAY = 7,
};
enum EnumClimateMode : uint32_t {
enum ClimateMode : uint32_t {
CLIMATE_MODE_OFF = 0,
CLIMATE_MODE_AUTO = 1,
CLIMATE_MODE_COOL = 2,
CLIMATE_MODE_HEAT = 3,
};
enum EnumClimateAction : uint32_t {
enum ClimateAction : uint32_t {
CLIMATE_ACTION_OFF = 0,
CLIMATE_ACTION_COOLING = 2,
CLIMATE_ACTION_HEATING = 3,
};
} // namespace enums
class HelloRequest : public ProtoMessage {
public:
std::string client_info{}; // NOLINT
@@ -183,8 +188,9 @@ class ListEntitiesBinarySensorResponse : public ProtoMessage {
};
class BinarySensorStateResponse : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
bool state{false}; // NOLINT
uint32_t key{0}; // NOLINT
bool state{false}; // NOLINT
bool missing_state{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -212,11 +218,11 @@ class ListEntitiesCoverResponse : public ProtoMessage {
};
class CoverStateResponse : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
EnumLegacyCoverState legacy_state{}; // NOLINT
float position{0.0f}; // NOLINT
float tilt{0.0f}; // NOLINT
EnumCoverOperation current_operation{}; // NOLINT
uint32_t key{0}; // NOLINT
enums::LegacyCoverState legacy_state{}; // NOLINT
float position{0.0f}; // NOLINT
float tilt{0.0f}; // NOLINT
enums::CoverOperation current_operation{}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -226,14 +232,14 @@ class CoverStateResponse : public ProtoMessage {
};
class CoverCommandRequest : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
bool has_legacy_command{false}; // NOLINT
EnumLegacyCoverCommand legacy_command{}; // NOLINT
bool has_position{false}; // NOLINT
float position{0.0f}; // NOLINT
bool has_tilt{false}; // NOLINT
float tilt{0.0f}; // NOLINT
bool stop{false}; // NOLINT
uint32_t key{0}; // NOLINT
bool has_legacy_command{false}; // NOLINT
enums::LegacyCoverCommand legacy_command{}; // NOLINT
bool has_position{false}; // NOLINT
float position{0.0f}; // NOLINT
bool has_tilt{false}; // NOLINT
float tilt{0.0f}; // NOLINT
bool stop{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -262,7 +268,7 @@ class FanStateResponse : public ProtoMessage {
uint32_t key{0}; // NOLINT
bool state{false}; // NOLINT
bool oscillating{false}; // NOLINT
EnumFanSpeed speed{}; // NOLINT
enums::FanSpeed speed{}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -276,7 +282,7 @@ class FanCommandRequest : public ProtoMessage {
bool has_state{false}; // NOLINT
bool state{false}; // NOLINT
bool has_speed{false}; // NOLINT
EnumFanSpeed speed{}; // NOLINT
enums::FanSpeed speed{}; // NOLINT
bool has_oscillating{false}; // NOLINT
bool oscillating{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
@@ -364,6 +370,7 @@ class ListEntitiesSensorResponse : public ProtoMessage {
std::string icon{}; // NOLINT
std::string unit_of_measurement{}; // NOLINT
int32_t accuracy_decimals{0}; // NOLINT
bool force_update{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -374,13 +381,15 @@ class ListEntitiesSensorResponse : public ProtoMessage {
};
class SensorStateResponse : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
float state{0.0f}; // NOLINT
uint32_t key{0}; // NOLINT
float state{0.0f}; // NOLINT
bool missing_state{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
protected:
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class ListEntitiesSwitchResponse : public ProtoMessage {
public:
@@ -436,18 +445,20 @@ class ListEntitiesTextSensorResponse : public ProtoMessage {
};
class TextSensorStateResponse : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
std::string state{}; // NOLINT
uint32_t key{0}; // NOLINT
std::string state{}; // NOLINT
bool missing_state{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
protected:
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
};
class SubscribeLogsRequest : public ProtoMessage {
public:
EnumLogLevel level{}; // NOLINT
enums::LogLevel level{}; // NOLINT
bool dump_config{false}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -457,7 +468,7 @@ class SubscribeLogsRequest : public ProtoMessage {
};
class SubscribeLogsResponse : public ProtoMessage {
public:
EnumLogLevel level{}; // NOLINT
enums::LogLevel level{}; // NOLINT
std::string tag{}; // NOLINT
std::string message{}; // NOLINT
bool send_failed{false}; // NOLINT
@@ -543,8 +554,8 @@ class GetTimeResponse : public ProtoMessage {
};
class ListEntitiesServicesArgument : public ProtoMessage {
public:
std::string name{}; // NOLINT
EnumServiceArgType type{}; // NOLINT
std::string name{}; // NOLINT
enums::ServiceArgType type{}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -638,7 +649,7 @@ class ListEntitiesClimateResponse : public ProtoMessage {
std::string unique_id{}; // NOLINT
bool supports_current_temperature{false}; // NOLINT
bool supports_two_point_target_temperature{false}; // NOLINT
std::vector<EnumClimateMode> supported_modes{}; // NOLINT
std::vector<enums::ClimateMode> supported_modes{}; // NOLINT
float visual_min_temperature{0.0f}; // NOLINT
float visual_max_temperature{0.0f}; // NOLINT
float visual_temperature_step{0.0f}; // NOLINT
@@ -655,13 +666,13 @@ class ListEntitiesClimateResponse : public ProtoMessage {
class ClimateStateResponse : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
EnumClimateMode mode{}; // NOLINT
enums::ClimateMode mode{}; // NOLINT
float current_temperature{0.0f}; // NOLINT
float target_temperature{0.0f}; // NOLINT
float target_temperature_low{0.0f}; // NOLINT
float target_temperature_high{0.0f}; // NOLINT
bool away{false}; // NOLINT
EnumClimateAction action{}; // NOLINT
enums::ClimateAction action{}; // NOLINT
void encode(ProtoWriteBuffer buffer) const override;
void dump_to(std::string &out) const override;
@@ -673,7 +684,7 @@ class ClimateCommandRequest : public ProtoMessage {
public:
uint32_t key{0}; // NOLINT
bool has_mode{false}; // NOLINT
EnumClimateMode mode{}; // NOLINT
enums::ClimateMode mode{}; // NOLINT
bool has_target_temperature{false}; // NOLINT
float target_temperature{0.0f}; // NOLINT
bool has_target_temperature_low{false}; // NOLINT

View File

@@ -7,9 +7,6 @@ namespace api {
#ifdef USE_BINARY_SENSOR
bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
if (!binary_sensor->has_state())
return true;
return this->client_->send_binary_sensor_state(binary_sensor, binary_sensor->state);
}
#endif
@@ -24,9 +21,6 @@ bool InitialStateIterator::on_light(light::LightState *light) { return this->cli
#endif
#ifdef USE_SENSOR
bool InitialStateIterator::on_sensor(sensor::Sensor *sensor) {
if (!sensor->has_state())
return true;
return this->client_->send_sensor_state(sensor, sensor->state);
}
#endif
@@ -37,9 +31,6 @@ bool InitialStateIterator::on_switch(switch_::Switch *a_switch) {
#endif
#ifdef USE_TEXT_SENSOR
bool InitialStateIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
if (!text_sensor->has_state())
return true;
return this->client_->send_text_sensor_state(text_sensor, text_sensor->state);
}
#endif

View File

@@ -25,14 +25,18 @@ template<> std::vector<std::string> get_execute_arg_value<std::vector<std::strin
return arg.string_array;
}
template<> EnumServiceArgType to_service_arg_type<bool>() { return SERVICE_ARG_TYPE_BOOL; }
template<> EnumServiceArgType to_service_arg_type<int>() { return SERVICE_ARG_TYPE_INT; }
template<> EnumServiceArgType to_service_arg_type<float>() { return SERVICE_ARG_TYPE_FLOAT; }
template<> EnumServiceArgType to_service_arg_type<std::string>() { return SERVICE_ARG_TYPE_STRING; }
template<> EnumServiceArgType to_service_arg_type<std::vector<bool>>() { return SERVICE_ARG_TYPE_BOOL_ARRAY; }
template<> EnumServiceArgType to_service_arg_type<std::vector<int>>() { return SERVICE_ARG_TYPE_INT_ARRAY; }
template<> EnumServiceArgType to_service_arg_type<std::vector<float>>() { return SERVICE_ARG_TYPE_FLOAT_ARRAY; }
template<> EnumServiceArgType to_service_arg_type<std::vector<std::string>>() { return SERVICE_ARG_TYPE_STRING_ARRAY; }
template<> enums::ServiceArgType to_service_arg_type<bool>() { return enums::SERVICE_ARG_TYPE_BOOL; }
template<> enums::ServiceArgType to_service_arg_type<int>() { return enums::SERVICE_ARG_TYPE_INT; }
template<> enums::ServiceArgType to_service_arg_type<float>() { return enums::SERVICE_ARG_TYPE_FLOAT; }
template<> enums::ServiceArgType to_service_arg_type<std::string>() { return enums::SERVICE_ARG_TYPE_STRING; }
template<> enums::ServiceArgType to_service_arg_type<std::vector<bool>>() { return enums::SERVICE_ARG_TYPE_BOOL_ARRAY; }
template<> enums::ServiceArgType to_service_arg_type<std::vector<int>>() { return enums::SERVICE_ARG_TYPE_INT_ARRAY; }
template<> enums::ServiceArgType to_service_arg_type<std::vector<float>>() {
return enums::SERVICE_ARG_TYPE_FLOAT_ARRAY;
}
template<> enums::ServiceArgType to_service_arg_type<std::vector<std::string>>() {
return enums::SERVICE_ARG_TYPE_STRING_ARRAY;
}
} // namespace api
} // namespace esphome

View File

@@ -16,7 +16,7 @@ class UserServiceDescriptor {
template<typename T> T get_execute_arg_value(const ExecuteServiceArgument &arg);
template<typename T> EnumServiceArgType to_service_arg_type();
template<typename T> enums::ServiceArgType to_service_arg_type();
template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
public:
@@ -29,7 +29,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
ListEntitiesServicesResponse msg;
msg.name = this->name_;
msg.key = this->key_;
std::array<EnumServiceArgType, sizeof...(Ts)> arg_types = {to_service_arg_type<Ts>()...};
std::array<enums::ServiceArgType, sizeof...(Ts)> arg_types = {to_service_arg_type<Ts>()...};
for (int i = 0; i < sizeof...(Ts); i++) {
ListEntitiesServicesArgument arg;
arg.type = arg_types[i];

View File

@@ -1,12 +1,11 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import CONF_PIN, CONF_INDOOR, CONF_WATCHDOG_THRESHOLD, \
from esphome.const import CONF_INDOOR, CONF_WATCHDOG_THRESHOLD, \
CONF_NOISE_LEVEL, CONF_SPIKE_REJECTION, CONF_LIGHTNING_THRESHOLD, \
CONF_MASK_DISTURBER, CONF_DIV_RATIO, CONF_CAPACITANCE
from esphome.core import coroutine
AUTO_LOAD = ['sensor', 'binary_sensor']
MULTI_CONF = True
@@ -15,10 +14,10 @@ CONF_AS3935_ID = 'as3935_id'
as3935_ns = cg.esphome_ns.namespace('as3935')
AS3935 = as3935_ns.class_('AS3935Component', cg.Component)
CONF_IRQ_PIN = 'irq_pin'
AS3935_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(AS3935),
cv.Required(CONF_PIN): cv.All(pins.internal_gpio_input_pin_schema,
pins.validate_has_interrupt),
cv.Required(CONF_IRQ_PIN): pins.gpio_input_pin_schema,
cv.Optional(CONF_INDOOR, default=True): cv.boolean,
cv.Optional(CONF_NOISE_LEVEL, default=2): cv.int_range(min=1, max=7),
@@ -35,8 +34,8 @@ AS3935_SCHEMA = cv.Schema({
def setup_as3935(var, config):
yield cg.register_component(var, config)
pin = yield cg.gpio_pin_expression(config[CONF_PIN])
cg.add(var.set_pin(pin))
irq_pin = yield cg.gpio_pin_expression(config[CONF_IRQ_PIN])
cg.add(var.set_irq_pin(irq_pin))
cg.add(var.set_indoor(config[CONF_INDOOR]))
cg.add(var.set_noise_level(config[CONF_NOISE_LEVEL]))
cg.add(var.set_watchdog_threshold(config[CONF_WATCHDOG_THRESHOLD]))

View File

@@ -9,10 +9,8 @@ static const char *TAG = "as3935";
void AS3935Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up AS3935...");
this->pin_->setup();
this->store_.pin = this->pin_->to_isr();
LOG_PIN(" Interrupt Pin: ", this->pin_);
this->pin_->attach_interrupt(AS3935ComponentStore::gpio_intr, &this->store_, RISING);
this->irq_pin_->setup();
LOG_PIN(" IRQ Pin: ", this->irq_pin_);
// Write properties to sensor
this->write_indoor(this->indoor_);
@@ -27,13 +25,13 @@ void AS3935Component::setup() {
void AS3935Component::dump_config() {
ESP_LOGCONFIG(TAG, "AS3935:");
LOG_PIN(" Interrupt Pin: ", this->pin_);
LOG_PIN(" Interrupt Pin: ", this->irq_pin_);
}
float AS3935Component::get_setup_priority() const { return setup_priority::DATA; }
void AS3935Component::loop() {
if (!this->store_.interrupt)
if (!this->irq_pin_->digital_read())
return;
uint8_t int_value = this->read_interrupt_register_();
@@ -53,7 +51,6 @@ void AS3935Component::loop() {
this->energy_sensor_->publish_state(energy);
}
this->thunder_alert_binary_sensor_->publish_state(false);
this->store_.interrupt = false;
}
void AS3935Component::write_indoor(bool indoor) {
@@ -222,7 +219,5 @@ uint8_t AS3935Component::read_register_(uint8_t reg, uint8_t mask) {
return value;
}
void ICACHE_RAM_ATTR AS3935ComponentStore::gpio_intr(AS3935ComponentStore *arg) { arg->interrupt = true; }
} // namespace as3935
} // namespace esphome

View File

@@ -50,14 +50,6 @@ enum AS3935Values {
NOISE_INT = 0x01
};
/// Store data in a class that doesn't use multiple-inheritance (vtables in flash)
struct AS3935ComponentStore {
volatile bool interrupt;
ISRInternalGPIOPin *pin;
static void gpio_intr(AS3935ComponentStore *arg);
};
class AS3935Component : public Component {
public:
void setup() override;
@@ -65,7 +57,7 @@ class AS3935Component : public Component {
float get_setup_priority() const override;
void loop() override;
void set_pin(GPIOPin *pin) { pin_ = pin; }
void set_irq_pin(GPIOPin *irq_pin) { irq_pin_ = irq_pin; }
void set_distance_sensor(sensor::Sensor *distance_sensor) { distance_sensor_ = distance_sensor; }
void set_energy_sensor(sensor::Sensor *energy_sensor) { energy_sensor_ = energy_sensor; }
void set_thunder_alert_binary_sensor(binary_sensor::BinarySensor *thunder_alert_binary_sensor) {
@@ -102,8 +94,7 @@ class AS3935Component : public Component {
sensor::Sensor *distance_sensor_;
sensor::Sensor *energy_sensor_;
binary_sensor::BinarySensor *thunder_alert_binary_sensor_;
GPIOPin *pin_;
AS3935ComponentStore store_;
GPIOPin *irq_pin_;
bool indoor_;
uint8_t noise_level_;

View File

@@ -31,6 +31,10 @@ uint8_t I2CAS3935Component::read_register(uint8_t reg) {
}
return value;
}
void I2CAS3935Component::dump_config() {
AS3935Component::dump_config();
LOG_I2C_DEVICE(this);
}
} // namespace as3935_i2c
} // namespace esphome

View File

@@ -10,6 +10,9 @@ namespace esphome {
namespace as3935_i2c {
class I2CAS3935Component : public as3935::AS3935Component, public i2c::I2CDevice {
public:
void dump_config() override;
protected:
void write_register(uint8_t reg, uint8_t mask, uint8_t bits, uint8_t start_position) override;
uint8_t read_register(uint8_t reg) override;

View File

@@ -1,23 +1,13 @@
# Dummy integration to allow relying on AsyncTCP
import esphome.codegen as cg
from esphome.const import ARDUINO_VERSION_ESP32_1_0_0, ARDUINO_VERSION_ESP32_1_0_1, \
ARDUINO_VERSION_ESP32_1_0_2
from esphome.core import CORE, coroutine_with_priority
@coroutine_with_priority(200.0)
def to_code(config):
if CORE.is_esp32:
# https://github.com/me-no-dev/AsyncTCP/blob/master/library.json
versions_requiring_older_asynctcp = [
ARDUINO_VERSION_ESP32_1_0_0,
ARDUINO_VERSION_ESP32_1_0_1,
ARDUINO_VERSION_ESP32_1_0_2,
]
if CORE.arduino_version in versions_requiring_older_asynctcp:
cg.add_library('AsyncTCP', '1.0.3')
else:
cg.add_library('AsyncTCP', '1.1.1')
# https://github.com/OttoWinter/AsyncTCP/blob/master/library.json
cg.add_library('AsyncTCP-esphome', '1.1.1')
elif CORE.is_esp8266:
# https://github.com/OttoWinter/ESPAsyncTCP
cg.add_library('ESPAsyncTCP-esphome', '1.2.2')

View File

@@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome.components import sensor, spi
from esphome.const import \
CONF_ID, CONF_VOLTAGE, CONF_CURRENT, CONF_POWER, CONF_FREQUENCY, \
ICON_FLASH, UNIT_HZ, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT
ICON_FLASH, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT, UNIT_HERTZ, ICON_CURRENT_AC
CONF_PHASE_A = 'phase_a'
CONF_PHASE_B = 'phase_b'
@@ -39,7 +39,7 @@ CONFIG_SCHEMA = cv.Schema({
cv.Optional(CONF_PHASE_A): ATM90E32_PHASE_SCHEMA,
cv.Optional(CONF_PHASE_B): ATM90E32_PHASE_SCHEMA,
cv.Optional(CONF_PHASE_C): ATM90E32_PHASE_SCHEMA,
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(UNIT_HZ, ICON_FLASH, 1),
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(UNIT_HERTZ, ICON_CURRENT_AC, 1),
cv.Required(CONF_LINE_FREQUENCY): cv.enum(LINE_FREQS, upper=True),
cv.Optional(CONF_GAIN_PGA, default='2X'): cv.enum(PGA_GAINS, upper=True),
}).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA)

View File

@@ -145,6 +145,14 @@ Trigger<> *BangBangClimate::get_cool_trigger() const { return this->cool_trigger
void BangBangClimate::set_supports_cool(bool supports_cool) { this->supports_cool_ = supports_cool; }
Trigger<> *BangBangClimate::get_heat_trigger() const { return this->heat_trigger_; }
void BangBangClimate::set_supports_heat(bool supports_heat) { this->supports_heat_ = supports_heat; }
void BangBangClimate::dump_config() {
LOG_CLIMATE("", "Bang Bang Climate", this);
ESP_LOGCONFIG(TAG, " Supports HEAT: %s", YESNO(this->supports_heat_));
ESP_LOGCONFIG(TAG, " Supports COOL: %s", YESNO(this->supports_cool_));
ESP_LOGCONFIG(TAG, " Supports AWAY mode: %s", YESNO(this->supports_away_));
ESP_LOGCONFIG(TAG, " Default Target Temperature Low: %.1f°C", this->normal_config_.default_temperature_low);
ESP_LOGCONFIG(TAG, " Default Target Temperature High: %.1f°C", this->normal_config_.default_temperature_high);
}
BangBangClimateTargetTempConfig::BangBangClimateTargetTempConfig() = default;
BangBangClimateTargetTempConfig::BangBangClimateTargetTempConfig(float default_temperature_low,

View File

@@ -21,6 +21,7 @@ class BangBangClimate : public climate::Climate, public Component {
public:
BangBangClimate();
void setup() override;
void dump_config() override;
void set_sensor(sensor::Sensor *sensor);
Trigger<> *get_idle_trigger() const;

View File

@@ -24,4 +24,4 @@ def to_code(config):
if CONF_OSCILLATION_OUTPUT in config:
oscillation_output = yield cg.get_variable(config[CONF_OSCILLATION_OUTPUT])
cg.add(var.set_oscillation(oscillation_output))
cg.add(var.set_oscillating(oscillation_output))

View File

@@ -23,6 +23,7 @@ IS_PLATFORM_COMPONENT = True
binary_sensor_ns = cg.esphome_ns.namespace('binary_sensor')
BinarySensor = binary_sensor_ns.class_('BinarySensor', cg.Nameable)
BinarySensorInitiallyOff = binary_sensor_ns.class_('BinarySensorInitiallyOff', BinarySensor)
BinarySensorPtr = BinarySensor.operator('ptr')
# Triggers

View File

@@ -10,9 +10,9 @@ namespace binary_sensor {
#define LOG_BINARY_SENSOR(prefix, type, obj) \
if (obj != nullptr) { \
ESP_LOGCONFIG(TAG, prefix type " '%s'", obj->get_name().c_str()); \
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, type, obj->get_name().c_str()); \
if (!obj->get_device_class().empty()) { \
ESP_LOGCONFIG(TAG, prefix " Device Class: '%s'", obj->get_device_class().c_str()); \
ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, obj->get_device_class().c_str()); \
} \
}
@@ -67,7 +67,7 @@ class BinarySensor : public Nameable {
void send_state_internal(bool state, bool is_initial);
/// Return whether this binary sensor has outputted a state.
bool has_state() const;
virtual bool has_state() const;
virtual bool is_status_binary_sensor() const;
@@ -86,5 +86,10 @@ class BinarySensor : public Nameable {
Deduplicator<bool> publish_dedup_;
};
class BinarySensorInitiallyOff : public BinarySensor {
public:
bool has_state() const override { return true; }
};
} // namespace binary_sensor
} // namespace esphome

View File

@@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome.components import sensor, binary_sensor
from esphome.const import CONF_ID, CONF_CHANNELS, CONF_VALUE, CONF_TYPE, UNIT_EMPTY, \
ICON_CHECK_CIRCLE_OUTLINE, CONF_BINARY_SENSOR
ICON_CHECK_CIRCLE_OUTLINE, CONF_BINARY_SENSOR, CONF_GROUP
DEPENDENCIES = ['binary_sensor']
@@ -11,7 +11,6 @@ binary_sensor_map_ns = cg.esphome_ns.namespace('binary_sensor_map')
BinarySensorMap = binary_sensor_map_ns.class_('BinarySensorMap', cg.Component, sensor.Sensor)
SensorMapType = binary_sensor_map_ns.enum('SensorMapType')
CONF_GROUP = 'group'
SENSOR_MAP_TYPES = {
CONF_GROUP: SensorMapType.BINARY_SENSOR_MAP_TYPE_GROUP,
}

View File

@@ -9,7 +9,7 @@
namespace esphome {
namespace ble_presence {
class BLEPresenceDevice : public binary_sensor::BinarySensor,
class BLEPresenceDevice : public binary_sensor::BinarySensorInitiallyOff,
public esp32_ble_tracker::ESPBTDeviceListener,
public Component {
public:

View File

@@ -166,6 +166,7 @@ float CaptivePortal::get_setup_priority() const {
// Before WiFi
return setup_priority::WIFI + 1.0f;
}
void CaptivePortal::dump_config() { ESP_LOGCONFIG(TAG, "Captive Portal:"); }
CaptivePortal *global_captive_portal = nullptr;

View File

@@ -2,6 +2,7 @@
#include <DNSServer.h>
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/core/preferences.h"
#include "esphome/components/web_server_base/web_server_base.h"
@@ -18,6 +19,7 @@ class CaptivePortal : public AsyncWebHandler, public Component {
public:
CaptivePortal(web_server_base::WebServerBase *base);
void setup() override;
void dump_config() override;
void loop() override {
if (this->dns_server_ != nullptr)
this->dns_server_->processNextRequest();

View File

@@ -9,6 +9,11 @@
namespace esphome {
namespace climate {
#define LOG_CLIMATE(prefix, type, obj) \
if (obj != nullptr) { \
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, type, obj->get_name().c_str()); \
}
class Climate;
/** This class is used to encode all control actions on a climate device.

View File

@@ -0,0 +1,41 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate, remote_transmitter, remote_receiver, sensor, remote_base
from esphome.components.remote_base import CONF_RECEIVER_ID, CONF_TRANSMITTER_ID
from esphome.const import CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT, CONF_SENSOR
from esphome.core import coroutine
AUTO_LOAD = ['sensor', 'remote_base']
climate_ir_ns = cg.esphome_ns.namespace('climate_ir')
ClimateIR = climate_ir_ns.class_('ClimateIR', climate.Climate, cg.Component,
remote_base.RemoteReceiverListener)
CLIMATE_IR_SCHEMA = climate.CLIMATE_SCHEMA.extend({
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(remote_transmitter.RemoteTransmitterComponent),
cv.Optional(CONF_SUPPORTS_COOL, default=True): cv.boolean,
cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean,
cv.Optional(CONF_SENSOR): cv.use_id(sensor.Sensor),
}).extend(cv.COMPONENT_SCHEMA)
CLIMATE_IR_WITH_RECEIVER_SCHEMA = CLIMATE_IR_SCHEMA.extend({
cv.Optional(CONF_RECEIVER_ID): cv.use_id(remote_receiver.RemoteReceiverComponent),
})
@coroutine
def register_climate_ir(var, config):
yield cg.register_component(var, config)
yield climate.register_climate(var, config)
cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL]))
cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT]))
if CONF_SENSOR in config:
sens = yield cg.get_variable(config[CONF_SENSOR])
cg.add(var.set_sensor(sens))
if CONF_RECEIVER_ID in config:
receiver = yield cg.get_variable(config[CONF_RECEIVER_ID])
cg.add(receiver.register_listener(var))
transmitter = yield cg.get_variable(config[CONF_TRANSMITTER_ID])
cg.add(var.set_transmitter(transmitter))

View File

@@ -1,7 +1,10 @@
#include "climate_ir.h"
#include "esphome/core/log.h"
namespace esphome {
namespace climate {
namespace climate_ir {
static const char *TAG = "climate_ir";
climate::ClimateTraits ClimateIR::traits() {
auto traits = climate::ClimateTraits();
@@ -52,6 +55,13 @@ void ClimateIR::control(const climate::ClimateCall &call) {
this->transmit_state();
this->publish_state();
}
void ClimateIR::dump_config() {
LOG_CLIMATE("", "IR Climate", this);
ESP_LOGCONFIG(TAG, " Min. Temperature: %.1f°C", this->minimum_temperature_);
ESP_LOGCONFIG(TAG, " Max. Temperature: %.1f°C", this->maximum_temperature_);
ESP_LOGCONFIG(TAG, " Supports HEAT: %s", YESNO(this->supports_heat_));
ESP_LOGCONFIG(TAG, " Supports COOL: %s", YESNO(this->supports_cool_));
}
} // namespace climate
} // namespace climate_ir
} // namespace esphome

View File

@@ -6,7 +6,7 @@
#include "esphome/components/sensor/sensor.h"
namespace esphome {
namespace climate {
namespace climate_ir {
/* A base for climate which works by sending (and receiving) IR codes
@@ -25,6 +25,7 @@ class ClimateIR : public climate::Climate, public Component, public remote_base:
}
void setup() override;
void dump_config() override;
void set_transmitter(remote_transmitter::RemoteTransmitterComponent *transmitter) {
this->transmitter_ = transmitter;
}
@@ -41,7 +42,10 @@ class ClimateIR : public climate::Climate, public Component, public remote_base:
climate::ClimateTraits traits() override;
/// Transmit via IR the state of this climate controller.
virtual void transmit_state() {}
virtual void transmit_state() = 0;
// Dummy implement on_receive so implementation is optional for inheritors
bool on_receive(remote_base::RemoteReceiveData data) override { return false; };
bool supports_cool_{true};
bool supports_heat_{true};
@@ -49,5 +53,6 @@ class ClimateIR : public climate::Climate, public Component, public remote_base:
remote_transmitter::RemoteTransmitterComponent *transmitter_;
sensor::Sensor *sensor_{nullptr};
};
} // namespace climate
} // namespace climate_ir
} // namespace esphome

View File

@@ -1,41 +1,18 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate, remote_transmitter, remote_receiver, sensor
from esphome.const import CONF_ID, CONF_SENSOR
from esphome.components import climate_ir
from esphome.const import CONF_ID
AUTO_LOAD = ['sensor', 'climate_ir']
AUTO_LOAD = ['climate_ir']
coolix_ns = cg.esphome_ns.namespace('coolix')
CoolixClimate = coolix_ns.class_('CoolixClimate', climate.Climate, cg.Component)
CoolixClimate = coolix_ns.class_('CoolixClimate', climate_ir.ClimateIR)
CONF_TRANSMITTER_ID = 'transmitter_id'
CONF_RECEIVER_ID = 'receiver_id'
CONF_SUPPORTS_HEAT = 'supports_heat'
CONF_SUPPORTS_COOL = 'supports_cool'
CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(CoolixClimate),
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(remote_transmitter.RemoteTransmitterComponent),
cv.Optional(CONF_RECEIVER_ID): cv.use_id(remote_receiver.RemoteReceiverComponent),
cv.Optional(CONF_SUPPORTS_COOL, default=True): cv.boolean,
cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean,
cv.Optional(CONF_SENSOR): cv.use_id(sensor.Sensor),
}).extend(cv.COMPONENT_SCHEMA))
})
def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield climate.register_climate(var, config)
cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL]))
cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT]))
if CONF_SENSOR in config:
sens = yield cg.get_variable(config[CONF_SENSOR])
cg.add(var.set_sensor(sens))
if CONF_RECEIVER_ID in config:
receiver = yield cg.get_variable(config[CONF_RECEIVER_ID])
cg.add(receiver.register_listener(var))
transmitter = yield cg.get_variable(config[CONF_TRANSMITTER_ID])
cg.add(var.set_transmitter(transmitter))
yield climate_ir.register_climate_ir(var, config)

View File

@@ -9,9 +9,9 @@ namespace coolix {
const uint8_t COOLIX_TEMP_MIN = 17; // Celsius
const uint8_t COOLIX_TEMP_MAX = 30; // Celsius
class CoolixClimate : public climate::ClimateIR {
class CoolixClimate : public climate_ir::ClimateIR {
public:
CoolixClimate() : climate::ClimateIR(COOLIX_TEMP_MIN, COOLIX_TEMP_MAX) {}
CoolixClimate() : climate_ir::ClimateIR(COOLIX_TEMP_MIN, COOLIX_TEMP_MAX) {}
protected:
/// Transmit via IR the state of this climate controller.

View File

@@ -13,13 +13,13 @@ const extern float COVER_CLOSED;
#define LOG_COVER(prefix, type, obj) \
if (obj != nullptr) { \
ESP_LOGCONFIG(TAG, prefix type " '%s'", obj->get_name().c_str()); \
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, type, obj->get_name().c_str()); \
auto traits_ = obj->get_traits(); \
if (traits_.get_is_assumed_state()) { \
ESP_LOGCONFIG(TAG, prefix " Assumed State: YES"); \
ESP_LOGCONFIG(TAG, "%s Assumed State: YES", prefix); \
} \
if (!obj->get_device_class().empty()) { \
ESP_LOGCONFIG(TAG, prefix " Device Class: '%s'", obj->get_device_class().c_str()); \
ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, obj->get_device_class().c_str()); \
} \
}

View File

@@ -1,13 +1,12 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import output
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE, CONF_BINARY
from .. import custom_ns
CustomBinaryOutputConstructor = custom_ns.class_('CustomBinaryOutputConstructor')
CustomFloatOutputConstructor = custom_ns.class_('CustomFloatOutputConstructor')
CONF_BINARY = 'binary'
CONF_FLOAT = 'float'
CONFIG_SCHEMA = cv.typed_schema({

View File

@@ -32,9 +32,11 @@ void DallasComponent::setup() {
ESP_LOGCONFIG(TAG, "Setting up DallasComponent...");
yield();
disable_interrupts();
std::vector<uint64_t> raw_sensors = this->one_wire_->search_vec();
enable_interrupts();
std::vector<uint64_t> raw_sensors;
{
InterruptLock lock;
raw_sensors = this->one_wire_->search_vec();
}
for (auto &address : raw_sensors) {
std::string s = uint64_to_string(address);
@@ -108,16 +110,17 @@ DallasTemperatureSensor *DallasComponent::get_sensor_by_index(uint8_t index, uin
void DallasComponent::update() {
this->status_clear_warning();
disable_interrupts();
bool result;
if (!this->one_wire_->reset()) {
result = false;
} else {
result = true;
this->one_wire_->skip();
this->one_wire_->write8(DALLAS_COMMAND_START_CONVERSION);
{
InterruptLock lock;
if (!this->one_wire_->reset()) {
result = false;
} else {
result = true;
this->one_wire_->skip();
this->one_wire_->write8(DALLAS_COMMAND_START_CONVERSION);
}
}
enable_interrupts();
if (!result) {
ESP_LOGE(TAG, "Requesting conversion failed");
@@ -127,9 +130,11 @@ void DallasComponent::update() {
for (auto *sensor : this->sensors_) {
this->set_timeout(sensor->get_address_name(), sensor->millis_to_wait_for_conversion(), [this, sensor] {
disable_interrupts();
bool res = sensor->read_scratch_pad();
enable_interrupts();
bool res;
{
InterruptLock lock;
res = sensor->read_scratch_pad();
}
if (!res) {
ESP_LOGW(TAG, "'%s' - Reseting bus for read failed!", sensor->get_name().c_str());
@@ -170,7 +175,7 @@ const std::string &DallasTemperatureSensor::get_address_name() {
return this->address_name_;
}
bool DallasTemperatureSensor::read_scratch_pad() {
bool ICACHE_RAM_ATTR DallasTemperatureSensor::read_scratch_pad() {
ESPOneWire *wire = this->parent_->one_wire_;
if (!wire->reset()) {
return false;
@@ -185,9 +190,11 @@ bool DallasTemperatureSensor::read_scratch_pad() {
return true;
}
bool DallasTemperatureSensor::setup_sensor() {
disable_interrupts();
bool r = this->read_scratch_pad();
enable_interrupts();
bool r;
{
InterruptLock lock;
r = this->read_scratch_pad();
}
if (!r) {
ESP_LOGE(TAG, "Reading scratchpad failed: reset");
@@ -222,20 +229,21 @@ bool DallasTemperatureSensor::setup_sensor() {
}
ESPOneWire *wire = this->parent_->one_wire_;
disable_interrupts();
if (wire->reset()) {
wire->select(this->address_);
wire->write8(DALLAS_COMMAND_WRITE_SCRATCH_PAD);
wire->write8(this->scratch_pad_[2]); // high alarm temp
wire->write8(this->scratch_pad_[3]); // low alarm temp
wire->write8(this->scratch_pad_[4]); // resolution
wire->reset();
{
InterruptLock lock;
if (wire->reset()) {
wire->select(this->address_);
wire->write8(DALLAS_COMMAND_WRITE_SCRATCH_PAD);
wire->write8(this->scratch_pad_[2]); // high alarm temp
wire->write8(this->scratch_pad_[3]); // low alarm temp
wire->write8(this->scratch_pad_[4]); // resolution
wire->reset();
// write value to EEPROM
wire->select(this->address_);
wire->write8(0x48);
// write value to EEPROM
wire->select(this->address_);
wire->write8(0x48);
}
}
enable_interrupts();
delay(20); // allow it to finish operation
wire->reset();

View File

@@ -12,7 +12,7 @@ const int ONE_WIRE_ROM_SEARCH = 0xF0;
ESPOneWire::ESPOneWire(GPIOPin *pin) : pin_(pin) {}
bool HOT ESPOneWire::reset() {
bool HOT ICACHE_RAM_ATTR ESPOneWire::reset() {
uint8_t retries = 125;
// Wait for communication to clear
@@ -39,7 +39,7 @@ bool HOT ESPOneWire::reset() {
return r;
}
void HOT ESPOneWire::write_bit(bool bit) {
void HOT ICACHE_RAM_ATTR ESPOneWire::write_bit(bool bit) {
// Initiate write/read by pulling low.
this->pin_->pin_mode(OUTPUT);
this->pin_->digital_write(false);
@@ -60,7 +60,7 @@ void HOT ESPOneWire::write_bit(bool bit) {
}
}
bool HOT ESPOneWire::read_bit() {
bool HOT ICACHE_RAM_ATTR ESPOneWire::read_bit() {
// Initiate read slot by pulling LOW for at least 1µs
this->pin_->pin_mode(OUTPUT);
this->pin_->digital_write(false);
@@ -76,43 +76,43 @@ bool HOT ESPOneWire::read_bit() {
return r;
}
void ESPOneWire::write8(uint8_t val) {
void ICACHE_RAM_ATTR ESPOneWire::write8(uint8_t val) {
for (uint8_t i = 0; i < 8; i++) {
this->write_bit(bool((1u << i) & val));
}
}
void ESPOneWire::write64(uint64_t val) {
void ICACHE_RAM_ATTR ESPOneWire::write64(uint64_t val) {
for (uint8_t i = 0; i < 64; i++) {
this->write_bit(bool((1ULL << i) & val));
}
}
uint8_t ESPOneWire::read8() {
uint8_t ICACHE_RAM_ATTR ESPOneWire::read8() {
uint8_t ret = 0;
for (uint8_t i = 0; i < 8; i++) {
ret |= (uint8_t(this->read_bit()) << i);
}
return ret;
}
uint64_t ESPOneWire::read64() {
uint64_t ICACHE_RAM_ATTR ESPOneWire::read64() {
uint64_t ret = 0;
for (uint8_t i = 0; i < 8; i++) {
ret |= (uint64_t(this->read_bit()) << i);
}
return ret;
}
void ESPOneWire::select(uint64_t address) {
void ICACHE_RAM_ATTR ESPOneWire::select(uint64_t address) {
this->write8(ONE_WIRE_ROM_SELECT);
this->write64(address);
}
void ESPOneWire::reset_search() {
void ICACHE_RAM_ATTR ESPOneWire::reset_search() {
this->last_discrepancy_ = 0;
this->last_device_flag_ = false;
this->last_family_discrepancy_ = 0;
this->rom_number_ = 0;
}
uint64_t HOT ESPOneWire::search() {
uint64_t HOT ICACHE_RAM_ATTR ESPOneWire::search() {
if (this->last_device_flag_) {
return 0u;
}
@@ -196,7 +196,7 @@ uint64_t HOT ESPOneWire::search() {
return this->rom_number_;
}
std::vector<uint64_t> ESPOneWire::search_vec() {
std::vector<uint64_t> ICACHE_RAM_ATTR ESPOneWire::search_vec() {
std::vector<uint64_t> res;
this->reset_search();
@@ -206,12 +206,12 @@ std::vector<uint64_t> ESPOneWire::search_vec() {
return res;
}
void ESPOneWire::skip() {
void ICACHE_RAM_ATTR ESPOneWire::skip() {
this->write8(0xCC); // skip ROM
}
GPIOPin *ESPOneWire::get_pin() { return this->pin_; }
uint8_t *ESPOneWire::rom_number8_() { return reinterpret_cast<uint8_t *>(&this->rom_number_); }
uint8_t ICACHE_RAM_ATTR *ESPOneWire::rom_number8_() { return reinterpret_cast<uint8_t *>(&this->rom_number_); }
} // namespace dallas
} // namespace esphome

View File

@@ -1,7 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.const import CONF_ID, CONF_TRIGGER_ID
from esphome.const import CONF_ID, CONF_TRIGGER_ID, CONF_FILE, CONF_DEVICE
from esphome.components import uart
DEPENDENCIES = ['uart']
@@ -14,10 +14,8 @@ DFPlayerIsPlayingCondition = dfplayer_ns.class_('DFPlayerIsPlayingCondition', au
MULTI_CONF = True
CONF_FOLDER = 'folder'
CONF_FILE = 'file'
CONF_LOOP = 'loop'
CONF_VOLUME = 'volume'
CONF_DEVICE = 'device'
CONF_EQ_PRESET = 'eq_preset'
CONF_ON_FINISHED_PLAYBACK = 'on_finished_playback'

View File

@@ -8,8 +8,10 @@ static const char* TAG = "dfplayer";
void DFPlayer::play_folder(uint16_t folder, uint16_t file) {
if (folder < 100 && file < 256) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x0F, (uint8_t) folder, (uint8_t) file);
} else if (folder <= 10 && file <= 1000) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x14, (((uint16_t) folder) << 12) | file);
} else {
ESP_LOGE(TAG, "Cannot play folder %d file %d.", folder, file);
@@ -93,6 +95,10 @@ void DFPlayer::loop() {
ESP_LOGI(TAG, "USB, TF Card available");
}
break;
case 0x40:
ESP_LOGV(TAG, "Nack");
this->ack_set_is_playing_ = false;
this->ack_reset_is_playing_ = false;
case 0x41:
ESP_LOGV(TAG, "Ack ok");
this->is_playing_ |= this->ack_set_is_playing_;
@@ -115,6 +121,10 @@ void DFPlayer::loop() {
this->read_pos_++;
}
}
void DFPlayer::dump_config() {
ESP_LOGCONFIG(TAG, "DFPlayer:");
this->check_uart_settings(9600);
}
} // namespace dfplayer
} // namespace esphome

View File

@@ -27,31 +27,59 @@ class DFPlayer : public uart::UARTDevice, public Component {
public:
void loop() override;
void next() { this->send_cmd_(0x01); }
void previous() { this->send_cmd_(0x02); }
void next() {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x01);
}
void previous() {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x02);
}
void play_file(uint16_t file) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x03, file);
}
void play_file_loop(uint16_t file) { this->send_cmd_(0x08, file); }
void play_file_loop(uint16_t file) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x08, file);
}
void play_folder(uint16_t folder, uint16_t file);
void play_folder_loop(uint16_t folder) { this->send_cmd_(0x17, folder); }
void play_folder_loop(uint16_t folder) {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x17, folder);
}
void volume_up() { this->send_cmd_(0x04); }
void volume_down() { this->send_cmd_(0x05); }
void set_device(Device device) { this->send_cmd_(0x09, device); }
void set_volume(uint8_t volume) { this->send_cmd_(0x06, volume); }
void set_eq(EqPreset preset) { this->send_cmd_(0x07, preset); }
void sleep() { this->send_cmd_(0x0A); }
void reset() { this->send_cmd_(0x0C); }
void start() { this->send_cmd_(0x0D); }
void sleep() {
this->ack_reset_is_playing_ = true;
this->send_cmd_(0x0A);
}
void reset() {
this->ack_reset_is_playing_ = true;
this->send_cmd_(0x0C);
}
void start() {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x0D);
}
void pause() {
this->ack_reset_is_playing_ = true;
this->send_cmd_(0x0E);
}
void stop() { this->send_cmd_(0x16); }
void random() { this->send_cmd_(0x18); }
void stop() {
this->ack_reset_is_playing_ = true;
this->send_cmd_(0x16);
}
void random() {
this->ack_set_is_playing_ = true;
this->send_cmd_(0x18);
}
bool is_playing() { return is_playing_; }
void dump_config() override;
void add_on_finished_playback_callback(std::function<void()> callback) {
this->on_finished_playback_callback_.add(std::move(callback));

View File

@@ -47,8 +47,10 @@ void DHT::update() {
if (error) {
ESP_LOGD(TAG, "Got Temperature=%.1f°C Humidity=%.1f%%", temperature, humidity);
this->temperature_sensor_->publish_state(temperature);
this->humidity_sensor_->publish_state(humidity);
if (this->temperature_sensor_ != nullptr)
this->temperature_sensor_->publish_state(temperature);
if (this->humidity_sensor_ != nullptr)
this->humidity_sensor_->publish_state(humidity);
this->status_clear_warning();
} else {
const char *str = "";
@@ -56,8 +58,10 @@ void DHT::update() {
str = " and consider manually specifying the DHT model using the model option";
}
ESP_LOGW(TAG, "Invalid readings! Please check your wiring (pull-up resistor, pin number)%s.", str);
this->temperature_sensor_->publish_state(NAN);
this->humidity_sensor_->publish_state(NAN);
if (this->temperature_sensor_ != nullptr)
this->temperature_sensor_->publish_state(NAN);
if (this->humidity_sensor_ != nullptr)
this->humidity_sensor_->publish_state(NAN);
this->status_set_warning();
}
}
@@ -67,80 +71,101 @@ void DHT::set_dht_model(DHTModel model) {
this->model_ = model;
this->is_auto_detect_ = model == DHT_MODEL_AUTO_DETECT;
}
bool HOT DHT::read_sensor_(float *temperature, float *humidity, bool report_errors) {
bool HOT ICACHE_RAM_ATTR DHT::read_sensor_(float *temperature, float *humidity, bool report_errors) {
*humidity = NAN;
*temperature = NAN;
disable_interrupts();
this->pin_->digital_write(false);
this->pin_->pin_mode(OUTPUT);
this->pin_->digital_write(false);
if (this->model_ == DHT_MODEL_DHT11) {
delayMicroseconds(18000);
} else if (this->model_ == DHT_MODEL_SI7021) {
delayMicroseconds(500);
this->pin_->digital_write(true);
delayMicroseconds(40);
} else {
delayMicroseconds(800);
}
this->pin_->pin_mode(INPUT_PULLUP);
delayMicroseconds(40);
int error_code = 0;
int8_t i = 0;
uint8_t data[5] = {0, 0, 0, 0, 0};
uint8_t bit = 7;
uint8_t byte = 0;
for (int8_t i = -1; i < 40; i++) {
uint32_t start_time = micros();
{
InterruptLock lock;
// Wait for rising edge
while (!this->pin_->digital_read()) {
if (micros() - start_time > 90) {
enable_interrupts();
if (report_errors) {
if (i < 0) {
ESP_LOGW(TAG, "Waiting for DHT communication to clear failed!");
} else {
ESP_LOGW(TAG, "Rising edge for bit %d failed!", i);
}
this->pin_->digital_write(false);
this->pin_->pin_mode(OUTPUT);
this->pin_->digital_write(false);
if (this->model_ == DHT_MODEL_DHT11) {
delayMicroseconds(18000);
} else if (this->model_ == DHT_MODEL_SI7021) {
delayMicroseconds(500);
this->pin_->digital_write(true);
delayMicroseconds(40);
} else {
delayMicroseconds(800);
}
this->pin_->pin_mode(INPUT_PULLUP);
delayMicroseconds(40);
uint8_t bit = 7;
uint8_t byte = 0;
for (i = -1; i < 40; i++) {
uint32_t start_time = micros();
// Wait for rising edge
while (!this->pin_->digital_read()) {
if (micros() - start_time > 90) {
if (i < 0)
error_code = 1;
else
error_code = 2;
break;
}
return false;
}
}
if (error_code != 0)
break;
start_time = micros();
uint32_t end_time = start_time;
start_time = micros();
uint32_t end_time = start_time;
// Wait for falling edge
while (this->pin_->digital_read()) {
if ((end_time = micros()) - start_time > 90) {
enable_interrupts();
if (report_errors) {
if (i < 0) {
ESP_LOGW(TAG, "Requesting data from DHT failed!");
} else {
ESP_LOGW(TAG, "Falling edge for bit %d failed!", i);
}
// Wait for falling edge
while (this->pin_->digital_read()) {
if ((end_time = micros()) - start_time > 90) {
if (i < 0)
error_code = 3;
else
error_code = 4;
break;
}
return false;
}
}
if (error_code != 0)
break;
if (i < 0)
continue;
if (i < 0)
continue;
if (end_time - start_time >= 40) {
data[byte] |= 1 << bit;
if (end_time - start_time >= 40) {
data[byte] |= 1 << bit;
}
if (bit == 0) {
bit = 7;
byte++;
} else
bit--;
}
if (bit == 0) {
bit = 7;
byte++;
} else
bit--;
}
enable_interrupts();
if (!report_errors && error_code != 0)
return false;
switch (error_code) {
case 1:
ESP_LOGW(TAG, "Waiting for DHT communication to clear failed!");
return false;
case 2:
ESP_LOGW(TAG, "Rising edge for bit %d failed!", i);
return false;
case 3:
ESP_LOGW(TAG, "Requesting data from DHT failed!");
return false;
case 4:
ESP_LOGW(TAG, "Falling edge for bit %d failed!", i);
return false;
case 0:
default:
break;
}
ESP_LOGVV(TAG,
"Data: Hum=0b" BYTE_TO_BINARY_PATTERN BYTE_TO_BINARY_PATTERN

View File

@@ -84,8 +84,8 @@ using display_writer_t = std::function<void(DisplayBuffer &)>;
#define LOG_DISPLAY(prefix, type, obj) \
if (obj != nullptr) { \
ESP_LOGCONFIG(TAG, prefix type); \
ESP_LOGCONFIG(TAG, prefix " Rotations: %d °", obj->rotation_); \
ESP_LOGCONFIG(TAG, prefix " Dimensions: %dpx x %dpx", obj->get_width(), obj->get_height()); \
ESP_LOGCONFIG(TAG, "%s Rotations: %d °", prefix, obj->rotation_); \
ESP_LOGCONFIG(TAG, "%s Dimensions: %dpx x %dpx", prefix, obj->get_width(), obj->get_height()); \
}
class DisplayBuffer {

View File

@@ -31,6 +31,11 @@ static esp_ble_adv_params_t ble_adv_params = {
static esp_ble_ibeacon_head_t ibeacon_common_head = {
.flags = {0x02, 0x01, 0x06}, .length = 0x1A, .type = 0xFF, .company_id = 0x004C, .beacon_type = 0x1502};
void ESP32BLEBeacon::dump_config() {
ESP_LOGCONFIG(TAG, "ESP32 BLE Beacon:");
ESP_LOGCONFIG(TAG, " Major: %u, Minor: %u", this->major_, this->minor_);
}
void ESP32BLEBeacon::setup() {
ESP_LOGCONFIG(TAG, "Setting up ESP32 BLE beacon...");
global_esp32_ble_beacon = this;
@@ -50,7 +55,7 @@ void ESP32BLEBeacon::ble_core_task(void *params) {
ble_setup();
while (true) {
delay(1000);
delay(1000); // NOLINT
}
}
void ESP32BLEBeacon::ble_setup() {

View File

@@ -34,6 +34,7 @@ class ESP32BLEBeacon : public Component {
explicit ESP32BLEBeacon(const std::array<uint8_t, 16> &uuid) : uuid_(uuid) {}
void setup() override;
void dump_config() override;
float get_setup_priority() const override;
void set_major(uint16_t major) { this->major_ = major; }

View File

@@ -37,7 +37,7 @@ CONFIG_SCHEMA = cv.Schema({
cv.Optional(CONF_SCAN_PARAMETERS, default={}): cv.All(cv.Schema({
cv.Optional(CONF_DURATION, default='5min'): cv.positive_time_period_seconds,
cv.Optional(CONF_INTERVAL, default='320ms'): cv.positive_time_period_milliseconds,
cv.Optional(CONF_WINDOW, default='200ms'): cv.positive_time_period_milliseconds,
cv.Optional(CONF_WINDOW, default='30ms'): cv.positive_time_period_milliseconds,
cv.Optional(CONF_ACTIVE, default=True): cv.boolean,
}), validate_scan_parameters),

View File

@@ -134,7 +134,7 @@ bool ESP32BLETracker::ble_setup() {
}
// BLE takes some time to be fully set up, 200ms should be more than enough
delay(200);
delay(200); // NOLINT
return true;
}
@@ -203,10 +203,6 @@ void ESP32BLETracker::gap_scan_result(const esp_ble_gap_cb_param_t::ble_scan_res
}
}
std::string hexencode_string(const std::string &raw_data) {
return hexencode(reinterpret_cast<const uint8_t *>(raw_data.c_str()), raw_data.size());
}
ESPBTUUID::ESPBTUUID() : uuid_() {}
ESPBTUUID ESPBTUUID::from_uint16(uint16_t uuid) {
ESPBTUUID ret;
@@ -266,13 +262,13 @@ std::string ESPBTUUID::to_string() {
}
ESPBLEiBeacon::ESPBLEiBeacon(const uint8_t *data) { memcpy(&this->beacon_data_, data, sizeof(beacon_data_)); }
optional<ESPBLEiBeacon> ESPBLEiBeacon::from_manufacturer_data(const std::string &data) {
if (data.size() != 25)
return {};
if (data[0] != 0x4C || data[1] != 0x00)
optional<ESPBLEiBeacon> ESPBLEiBeacon::from_manufacturer_data(const ServiceData &data) {
if (!data.uuid.contains(0x4C, 0x00))
return {};
return ESPBLEiBeacon(reinterpret_cast<const uint8_t *>(data.data()));
if (data.data.size() != 23)
return {};
return ESPBLEiBeacon(data.data.data());
}
void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param &param) {
@@ -304,8 +300,8 @@ void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_e
ESP_LOGVV(TAG, " RSSI: %d", this->rssi_);
ESP_LOGVV(TAG, " Name: '%s'", this->name_.c_str());
if (this->tx_power_.has_value()) {
ESP_LOGVV(TAG, " TX Power: %d", *this->tx_power_);
for (auto &it : this->tx_powers_) {
ESP_LOGVV(TAG, " TX Power: %d", it);
}
if (this->appearance_.has_value()) {
ESP_LOGVV(TAG, " Appearance: %u", *this->appearance_);
@@ -313,24 +309,25 @@ void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_e
if (this->ad_flag_.has_value()) {
ESP_LOGVV(TAG, " Ad Flag: %u", *this->ad_flag_);
}
for (auto uuid : this->service_uuids_) {
for (auto &uuid : this->service_uuids_) {
ESP_LOGVV(TAG, " Service UUID: %s", uuid.to_string().c_str());
}
ESP_LOGVV(TAG, " Manufacturer data: %s", hexencode_string(this->manufacturer_data_).c_str());
ESP_LOGVV(TAG, " Service data: %s", hexencode_string(this->service_data_).c_str());
if (this->service_data_uuid_.has_value()) {
ESP_LOGVV(TAG, " Service Data UUID: %s", this->service_data_uuid_->to_string().c_str());
for (auto &data : this->manufacturer_datas_) {
ESP_LOGVV(TAG, " Manufacturer data: %s", hexencode(data.data).c_str());
}
for (auto &data : this->service_datas_) {
ESP_LOGVV(TAG, " Service data:");
ESP_LOGVV(TAG, " UUID: %s", data.uuid.to_string().c_str());
ESP_LOGVV(TAG, " Data: %s", hexencode(data.data).c_str());
}
ESP_LOGVV(TAG, "Adv data: %s",
hexencode_string(std::string(reinterpret_cast<const char *>(param.ble_adv), param.adv_data_len)).c_str());
ESP_LOGVV(TAG, "Adv data: %s", hexencode(param.ble_adv, param.adv_data_len + param.scan_rsp_len).c_str());
#endif
}
void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param &param) {
size_t offset = 0;
const uint8_t *payload = param.ble_adv;
uint8_t len = param.adv_data_len;
uint8_t len = param.adv_data_len + param.scan_rsp_len;
while (offset + 2 < len) {
const uint8_t field_length = payload[offset++]; // First byte is length of adv record
@@ -343,25 +340,52 @@ void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_p
const uint8_t record_length = field_length - 1;
offset += record_length;
// See also Generic Access Profile Assigned Numbers:
// https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/ See also ADVERTISING AND SCAN
// RESPONSE DATA FORMAT: https://www.bluetooth.com/specifications/bluetooth-core-specification/ (vol 3, part C, 11)
// See also Core Specification Supplement: https://www.bluetooth.com/specifications/bluetooth-core-specification/
// (called CSS here)
switch (record_type) {
case ESP_BLE_AD_TYPE_NAME_CMPL: {
// CSS 1.2 LOCAL NAME
// "The Local Name data type shall be the same as, or a shortened version of, the local name assigned to the
// device." CSS 1: Optional in this context; shall not appear more than once in a block.
this->name_ = std::string(reinterpret_cast<const char *>(record), record_length);
break;
}
case ESP_BLE_AD_TYPE_TX_PWR: {
this->tx_power_ = *payload;
// CSS 1.5 TX POWER LEVEL
// "The TX Power Level data type indicates the transmitted power level of the packet containing the data type."
// CSS 1: Optional in this context (may appear more than once in a block).
this->tx_powers_.push_back(*payload);
break;
}
case ESP_BLE_AD_TYPE_APPEARANCE: {
// CSS 1.12 APPEARANCE
// "The Appearance data type defines the external appearance of the device."
// See also https://www.bluetooth.com/specifications/gatt/characteristics/
// CSS 1: Optional in this context; shall not appear more than once in a block and shall not appear in both
// the AD and SRD of the same extended advertising interval.
this->appearance_ = *reinterpret_cast<const uint16_t *>(record);
break;
}
case ESP_BLE_AD_TYPE_FLAG: {
// CSS 1.3 FLAGS
// "The Flags data type contains one bit Boolean flags. The Flags data type shall be included when any of the
// Flag bits are non-zero and the advertising packet is connectable, otherwise the Flags data type may be
// omitted."
// CSS 1: Optional in this context; shall not appear more than once in a block.
this->ad_flag_ = *record;
break;
}
// CSS 1.1 SERVICE UUID
// The Service UUID data type is used to include a list of Service or Service Class UUIDs.
// There are six data types defined for the three sizes of Service UUIDs that may be returned:
// CSS 1: Optional in this context (may appear more than once in a block).
case ESP_BLE_AD_TYPE_16SRV_CMPL:
case ESP_BLE_AD_TYPE_16SRV_PART: {
// • 16-bit Bluetooth Service UUIDs
for (uint8_t i = 0; i < record_length / 2; i++) {
this->service_uuids_.push_back(ESPBTUUID::from_uint16(*reinterpret_cast<const uint16_t *>(record + 2 * i)));
}
@@ -369,6 +393,7 @@ void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_p
}
case ESP_BLE_AD_TYPE_32SRV_CMPL:
case ESP_BLE_AD_TYPE_32SRV_PART: {
// • 32-bit Bluetooth Service UUIDs
for (uint8_t i = 0; i < record_length / 4; i++) {
this->service_uuids_.push_back(ESPBTUUID::from_uint32(*reinterpret_cast<const uint32_t *>(record + 4 * i)));
}
@@ -376,41 +401,70 @@ void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_p
}
case ESP_BLE_AD_TYPE_128SRV_CMPL:
case ESP_BLE_AD_TYPE_128SRV_PART: {
// • Global 128-bit Service UUIDs
this->service_uuids_.push_back(ESPBTUUID::from_raw(record));
break;
}
case ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE: {
this->manufacturer_data_ = std::string(reinterpret_cast<const char *>(record), record_length);
// CSS 1.4 MANUFACTURER SPECIFIC DATA
// "The Manufacturer Specific data type is used for manufacturer specific data. The first two data octets shall
// contain a company identifier from Assigned Numbers. The interpretation of any other octets within the data
// shall be defined by the manufacturer specified by the company identifier."
// CSS 1: Optional in this context (may appear more than once in a block).
if (record_length < 2) {
ESP_LOGV(TAG, "Record length too small for ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE");
break;
}
ServiceData data{};
data.uuid = ESPBTUUID::from_uint16(*reinterpret_cast<const uint16_t *>(record));
data.data.assign(record + 2UL, record + record_length);
this->manufacturer_datas_.push_back(data);
break;
}
// CSS 1.11 SERVICE DATA
// "The Service Data data type consists of a service UUID with the data associated with that service."
// CSS 1: Optional in this context (may appear more than once in a block).
case ESP_BLE_AD_TYPE_SERVICE_DATA: {
// «Service Data - 16 bit UUID»
// Size: 2 or more octets
// The first 2 octets contain the 16 bit Service UUID fol- lowed by additional service data
if (record_length < 2) {
ESP_LOGV(TAG, "Record length too small for ESP_BLE_AD_TYPE_SERVICE_DATA");
break;
}
this->service_data_uuid_ = ESPBTUUID::from_uint16(*reinterpret_cast<const uint16_t *>(record));
if (record_length > 2)
this->service_data_ = std::string(reinterpret_cast<const char *>(record + 2), record_length - 2UL);
ServiceData data{};
data.uuid = ESPBTUUID::from_uint16(*reinterpret_cast<const uint16_t *>(record));
data.data.assign(record + 2UL, record + record_length);
this->service_datas_.push_back(data);
break;
}
case ESP_BLE_AD_TYPE_32SERVICE_DATA: {
// «Service Data - 32 bit UUID»
// Size: 4 or more octets
// The first 4 octets contain the 32 bit Service UUID fol- lowed by additional service data
if (record_length < 4) {
ESP_LOGV(TAG, "Record length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA");
break;
}
this->service_data_uuid_ = ESPBTUUID::from_uint32(*reinterpret_cast<const uint32_t *>(record));
if (record_length > 4)
this->service_data_ = std::string(reinterpret_cast<const char *>(record + 4), record_length - 4UL);
ServiceData data{};
data.uuid = ESPBTUUID::from_uint32(*reinterpret_cast<const uint32_t *>(record));
data.data.assign(record + 4UL, record + record_length);
this->service_datas_.push_back(data);
break;
}
case ESP_BLE_AD_TYPE_128SERVICE_DATA: {
// «Service Data - 128 bit UUID»
// Size: 16 or more octets
// The first 16 octets contain the 128 bit Service UUID followed by additional service data
if (record_length < 16) {
ESP_LOGV(TAG, "Record length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA");
break;
}
this->service_data_uuid_ = ESPBTUUID::from_raw(record);
if (record_length > 16)
this->service_data_ = std::string(reinterpret_cast<const char *>(record + 16), record_length - 16UL);
ServiceData data{};
data.uuid = ESPBTUUID::from_raw(record);
data.data.assign(record + 16UL, record + record_length);
this->service_datas_.push_back(data);
break;
}
default: {
@@ -427,22 +481,12 @@ std::string ESPBTDevice::address_str() const {
return mac;
}
uint64_t ESPBTDevice::address_uint64() const { return ble_addr_to_uint64(this->address_); }
esp_ble_addr_type_t ESPBTDevice::get_address_type() const { return this->address_type_; }
int ESPBTDevice::get_rssi() const { return this->rssi_; }
const std::string &ESPBTDevice::get_name() const { return this->name_; }
const optional<int8_t> &ESPBTDevice::get_tx_power() const { return this->tx_power_; }
const optional<uint16_t> &ESPBTDevice::get_appearance() const { return this->appearance_; }
const optional<uint8_t> &ESPBTDevice::get_ad_flag() const { return this->ad_flag_; }
const std::vector<ESPBTUUID> &ESPBTDevice::get_service_uuids() const { return this->service_uuids_; }
const std::string &ESPBTDevice::get_manufacturer_data() const { return this->manufacturer_data_; }
const std::string &ESPBTDevice::get_service_data() const { return this->service_data_; }
const optional<ESPBTUUID> &ESPBTDevice::get_service_data_uuid() const { return this->service_data_uuid_; }
void ESP32BLETracker::dump_config() {
ESP_LOGCONFIG(TAG, "BLE Tracker:");
ESP_LOGCONFIG(TAG, " Scan Duration: %u s", this->scan_duration_);
ESP_LOGCONFIG(TAG, " Scan Interval: %u ms", this->scan_interval_);
ESP_LOGCONFIG(TAG, " Scan Window: %u ms", this->scan_window_);
ESP_LOGCONFIG(TAG, " Scan Interval: %.1f ms", this->scan_interval_ * 0.625f);
ESP_LOGCONFIG(TAG, " Scan Window: %.1f ms", this->scan_window_ * 0.625f);
ESP_LOGCONFIG(TAG, " Scan Type: %s", this->scan_active_ ? "ACTIVE" : "PASSIVE");
}
void ESP32BLETracker::print_bt_device_info(const ESPBTDevice &device) {
@@ -477,8 +521,8 @@ void ESP32BLETracker::print_bt_device_info(const ESPBTDevice &device) {
ESP_LOGD(TAG, " Address Type: %s", address_type_s);
if (!device.get_name().empty())
ESP_LOGD(TAG, " Name: '%s'", device.get_name().c_str());
if (device.get_tx_power().has_value()) {
ESP_LOGD(TAG, " TX Power: %d", *device.get_tx_power());
for (auto &tx_power : device.get_tx_powers()) {
ESP_LOGD(TAG, " TX Power: %d", tx_power);
}
}

View File

@@ -31,11 +31,18 @@ class ESPBTUUID {
esp_bt_uuid_t uuid_;
};
using adv_data_t = std::vector<uint8_t>;
struct ServiceData {
ESPBTUUID uuid;
adv_data_t data;
};
class ESPBLEiBeacon {
public:
ESPBLEiBeacon() { memset(&this->beacon_data_, 0, sizeof(this->beacon_data_)); }
ESPBLEiBeacon(const uint8_t *data);
static optional<ESPBLEiBeacon> from_manufacturer_data(const std::string &data);
static optional<ESPBLEiBeacon> from_manufacturer_data(const ServiceData &data);
uint16_t get_major() { return reverse_bits_16(this->beacon_data_.major); }
uint16_t get_minor() { return reverse_bits_16(this->beacon_data_.minor); }
@@ -44,7 +51,6 @@ class ESPBLEiBeacon {
protected:
struct {
uint16_t manufacturer_id;
uint8_t sub_type;
uint8_t proximity_uuid[16];
uint16_t major;
@@ -61,18 +67,33 @@ class ESPBTDevice {
uint64_t address_uint64() const;
esp_ble_addr_type_t get_address_type() const;
int get_rssi() const;
const std::string &get_name() const;
const optional<int8_t> &get_tx_power() const;
const optional<uint16_t> &get_appearance() const;
const optional<uint8_t> &get_ad_flag() const;
const std::vector<ESPBTUUID> &get_service_uuids() const;
const std::string &get_manufacturer_data() const;
const std::string &get_service_data() const;
const optional<ESPBTUUID> &get_service_data_uuid() const;
const optional<ESPBLEiBeacon> get_ibeacon() const {
return ESPBLEiBeacon::from_manufacturer_data(this->manufacturer_data_);
esp_ble_addr_type_t get_address_type() const { return this->address_type_; }
int get_rssi() const { return rssi_; }
const std::string &get_name() const { return this->name_; }
ESPDEPRECATED("Use get_tx_powers() instead")
optional<int8_t> get_tx_power() const {
if (this->tx_powers_.empty())
return {};
return this->tx_powers_[0];
}
const std::vector<int8_t> &get_tx_powers() const { return tx_powers_; }
const optional<uint16_t> &get_appearance() const { return appearance_; }
const optional<uint8_t> &get_ad_flag() const { return ad_flag_; }
const std::vector<ESPBTUUID> &get_service_uuids() const { return service_uuids_; }
const std::vector<ServiceData> &get_manufacturer_datas() const { return manufacturer_datas_; }
const std::vector<ServiceData> &get_service_datas() const { return service_datas_; }
optional<ESPBLEiBeacon> get_ibeacon() const {
for (auto &it : this->manufacturer_datas_) {
auto res = ESPBLEiBeacon::from_manufacturer_data(it);
if (res.has_value())
return *res;
}
return {};
}
protected:
@@ -84,13 +105,12 @@ class ESPBTDevice {
esp_ble_addr_type_t address_type_{BLE_ADDR_TYPE_PUBLIC};
int rssi_{0};
std::string name_{};
optional<int8_t> tx_power_{};
std::vector<int8_t> tx_powers_{};
optional<uint16_t> appearance_{};
optional<uint8_t> ad_flag_{};
std::vector<ESPBTUUID> service_uuids_;
std::string manufacturer_data_{};
std::string service_data_{};
optional<ESPBTUUID> service_data_uuid_{};
std::vector<ServiceData> manufacturer_datas_{};
std::vector<ServiceData> service_datas_{};
};
class ESP32BLETracker;

View File

@@ -2,7 +2,7 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_NAME, CONF_PIN, CONF_SCL, CONF_SDA, \
ESP_PLATFORM_ESP32
ESP_PLATFORM_ESP32, CONF_DATA_PINS, CONF_RESET_PIN, CONF_RESOLUTION, CONF_BRIGHTNESS
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['api']
@@ -35,23 +35,19 @@ FRAME_SIZES = {
'UXGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
}
CONF_DATA_PINS = 'data_pins'
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_RESET_PIN = 'reset_pin'
CONF_POWER_DOWN_PIN = 'power_down_pin'
CONF_MAX_FRAMERATE = 'max_framerate'
CONF_IDLE_FRAMERATE = 'idle_framerate'
CONF_RESOLUTION = 'resolution'
CONF_JPEG_QUALITY = 'jpeg_quality'
CONF_VERTICAL_FLIP = 'vertical_flip'
CONF_HORIZONTAL_MIRROR = 'horizontal_mirror'
CONF_CONTRAST = 'contrast'
CONF_BRIGHTNESS = 'brightness'
CONF_SATURATION = 'saturation'
CONF_TEST_PATTERN = 'test_pattern'

View File

@@ -85,6 +85,8 @@ void ESP32Camera::dump_config() {
case FRAMESIZE_UXGA:
ESP_LOGCONFIG(TAG, " Resolution: 1600x1200 (UXGA)");
break;
default:
break;
}
if (this->is_failed()) {

View File

@@ -108,6 +108,8 @@ void ESP32TouchComponent::dump_config() {
}
void ESP32TouchComponent::loop() {
const uint32_t now = millis();
bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
for (auto *child : this->children_) {
uint16_t value;
if (this->iir_filter_enabled_()) {
@@ -119,14 +121,14 @@ void ESP32TouchComponent::loop() {
child->value_ = value;
child->publish_state(value < child->get_threshold());
if (this->setup_mode_) {
if (should_print) {
ESP_LOGD(TAG, "Touch Pad '%s' (T%u): %u", child->get_name().c_str(), child->get_touch_pad(), value);
}
}
if (this->setup_mode_) {
if (should_print) {
// Avoid spamming logs
delay(250);
this->setup_mode_last_log_print_ = now;
}
}

View File

@@ -50,6 +50,7 @@ class ESP32TouchComponent : public Component {
touch_volt_atten_t voltage_attenuation_{};
std::vector<ESP32TouchBinarySensor *> children_;
bool setup_mode_{false};
uint32_t setup_mode_last_log_print_{};
uint32_t iir_filter_{0};
};

View File

@@ -0,0 +1,18 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate_ir
from esphome.const import CONF_ID
AUTO_LOAD = ['climate_ir']
fujitsu_general_ns = cg.esphome_ns.namespace('fujitsu_general')
FujitsuGeneralClimate = fujitsu_general_ns.class_('FujitsuGeneralClimate', climate_ir.ClimateIR)
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(FujitsuGeneralClimate),
})
def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield climate_ir.register_climate_ir(var, config)

View File

@@ -0,0 +1,212 @@
#include "fujitsu_general.h"
namespace esphome {
namespace fujitsu_general {
static const char *TAG = "fujitsu_general.climate";
// Control packet
const uint16_t FUJITSU_GENERAL_STATE_LENGTH = 16;
const uint8_t FUJITSU_GENERAL_BASE_BYTE0 = 0x14;
const uint8_t FUJITSU_GENERAL_BASE_BYTE1 = 0x63;
const uint8_t FUJITSU_GENERAL_BASE_BYTE2 = 0x00;
const uint8_t FUJITSU_GENERAL_BASE_BYTE3 = 0x10;
const uint8_t FUJITSU_GENERAL_BASE_BYTE4 = 0x10;
const uint8_t FUJITSU_GENERAL_BASE_BYTE5 = 0xFE;
const uint8_t FUJITSU_GENERAL_BASE_BYTE6 = 0x09;
const uint8_t FUJITSU_GENERAL_BASE_BYTE7 = 0x30;
// Temperature and POWER ON
const uint8_t FUJITSU_GENERAL_POWER_ON_MASK_BYTE8 = 0b00000001;
const uint8_t FUJITSU_GENERAL_BASE_BYTE8 = 0x40;
// Mode
const uint8_t FUJITSU_GENERAL_MODE_AUTO_BYTE9 = 0x00;
const uint8_t FUJITSU_GENERAL_MODE_HEAT_BYTE9 = 0x04;
const uint8_t FUJITSU_GENERAL_MODE_COOL_BYTE9 = 0x01;
const uint8_t FUJITSU_GENERAL_MODE_DRY_BYTE9 = 0x02;
const uint8_t FUJITSU_GENERAL_MODE_FAN_BYTE9 = 0x03;
const uint8_t FUJITSU_GENERAL_MODE_10C_BYTE9 = 0x0B;
const uint8_t FUJITSU_GENERAL_BASE_BYTE9 = 0x01;
// Fan speed and swing
const uint8_t FUJITSU_GENERAL_FAN_AUTO_BYTE10 = 0x00;
const uint8_t FUJITSU_GENERAL_FAN_HIGH_BYTE10 = 0x01;
const uint8_t FUJITSU_GENERAL_FAN_MEDIUM_BYTE10 = 0x02;
const uint8_t FUJITSU_GENERAL_FAN_LOW_BYTE10 = 0x03;
const uint8_t FUJITSU_GENERAL_FAN_SILENT_BYTE10 = 0x04;
const uint8_t FUJITSU_GENERAL_SWING_MASK_BYTE10 = 0b00010000;
const uint8_t FUJITSU_GENERAL_BASE_BYTE10 = 0x00;
const uint8_t FUJITSU_GENERAL_BASE_BYTE11 = 0x00;
const uint8_t FUJITSU_GENERAL_BASE_BYTE12 = 0x00;
const uint8_t FUJITSU_GENERAL_BASE_BYTE13 = 0x00;
// Outdoor Unit Low Noise
const uint8_t FUJITSU_GENERAL_OUTDOOR_UNIT_LOW_NOISE_BYTE14 = 0xA0;
const uint8_t FUJITSU_GENERAL_BASE_BYTE14 = 0x20;
// CRC
const uint8_t FUJITSU_GENERAL_BASE_BYTE15 = 0x6F;
// Power off packet is specific
const uint16_t FUJITSU_GENERAL_OFF_LENGTH = 7;
const uint8_t FUJITSU_GENERAL_OFF_BYTE0 = FUJITSU_GENERAL_BASE_BYTE0;
const uint8_t FUJITSU_GENERAL_OFF_BYTE1 = FUJITSU_GENERAL_BASE_BYTE1;
const uint8_t FUJITSU_GENERAL_OFF_BYTE2 = FUJITSU_GENERAL_BASE_BYTE2;
const uint8_t FUJITSU_GENERAL_OFF_BYTE3 = FUJITSU_GENERAL_BASE_BYTE3;
const uint8_t FUJITSU_GENERAL_OFF_BYTE4 = FUJITSU_GENERAL_BASE_BYTE4;
const uint8_t FUJITSU_GENERAL_OFF_BYTE5 = 0x02;
const uint8_t FUJITSU_GENERAL_OFF_BYTE6 = 0xFD;
const uint8_t FUJITSU_GENERAL_TEMP_MAX = 30; // Celsius
const uint8_t FUJITSU_GENERAL_TEMP_MIN = 16; // Celsius
const uint16_t FUJITSU_GENERAL_HEADER_MARK = 3300;
const uint16_t FUJITSU_GENERAL_HEADER_SPACE = 1600;
const uint16_t FUJITSU_GENERAL_BIT_MARK = 420;
const uint16_t FUJITSU_GENERAL_ONE_SPACE = 1200;
const uint16_t FUJITSU_GENERAL_ZERO_SPACE = 420;
const uint16_t FUJITSU_GENERAL_TRL_MARK = 420;
const uint16_t FUJITSU_GENERAL_TRL_SPACE = 8000;
const uint32_t FUJITSU_GENERAL_CARRIER_FREQUENCY = 38000;
FujitsuGeneralClimate::FujitsuGeneralClimate() : ClimateIR(FUJITSU_GENERAL_TEMP_MIN, FUJITSU_GENERAL_TEMP_MAX, 1) {}
void FujitsuGeneralClimate::transmit_state() {
if (this->mode == climate::CLIMATE_MODE_OFF) {
this->transmit_off_();
return;
}
uint8_t remote_state[FUJITSU_GENERAL_STATE_LENGTH] = {0};
remote_state[0] = FUJITSU_GENERAL_BASE_BYTE0;
remote_state[1] = FUJITSU_GENERAL_BASE_BYTE1;
remote_state[2] = FUJITSU_GENERAL_BASE_BYTE2;
remote_state[3] = FUJITSU_GENERAL_BASE_BYTE3;
remote_state[4] = FUJITSU_GENERAL_BASE_BYTE4;
remote_state[5] = FUJITSU_GENERAL_BASE_BYTE5;
remote_state[6] = FUJITSU_GENERAL_BASE_BYTE6;
remote_state[7] = FUJITSU_GENERAL_BASE_BYTE7;
remote_state[8] = FUJITSU_GENERAL_BASE_BYTE8;
remote_state[9] = FUJITSU_GENERAL_BASE_BYTE9;
remote_state[10] = FUJITSU_GENERAL_BASE_BYTE10;
remote_state[11] = FUJITSU_GENERAL_BASE_BYTE11;
remote_state[12] = FUJITSU_GENERAL_BASE_BYTE12;
remote_state[13] = FUJITSU_GENERAL_BASE_BYTE13;
remote_state[14] = FUJITSU_GENERAL_BASE_BYTE14;
remote_state[15] = FUJITSU_GENERAL_BASE_BYTE15;
// Set temperature
uint8_t safecelsius = std::max((uint8_t) this->target_temperature, FUJITSU_GENERAL_TEMP_MIN);
safecelsius = std::min(safecelsius, FUJITSU_GENERAL_TEMP_MAX);
remote_state[8] = (byte) safecelsius - 16;
remote_state[8] = remote_state[8] << 4;
// If not powered - set power on flag
if (!this->power_) {
remote_state[8] = (byte) remote_state[8] | FUJITSU_GENERAL_POWER_ON_MASK_BYTE8;
}
// Set mode
switch (this->mode) {
case climate::CLIMATE_MODE_COOL:
remote_state[9] = FUJITSU_GENERAL_MODE_COOL_BYTE9;
break;
case climate::CLIMATE_MODE_HEAT:
remote_state[9] = FUJITSU_GENERAL_MODE_HEAT_BYTE9;
break;
case climate::CLIMATE_MODE_AUTO:
default:
remote_state[9] = FUJITSU_GENERAL_MODE_AUTO_BYTE9;
break;
// TODO: CLIMATE_MODE_FAN_ONLY, CLIMATE_MODE_DRY, CLIMATE_MODE_10C are missing in esphome
}
// TODO: missing support for fan speed
remote_state[10] = FUJITSU_GENERAL_FAN_AUTO_BYTE10;
// TODO: missing support for swing
// remote_state[10] = (byte) remote_state[10] | FUJITSU_GENERAL_SWING_MASK_BYTE10;
// TODO: missing support for outdoor unit low noise
// remote_state[14] = (byte) remote_state[14] | FUJITSU_GENERAL_OUTDOOR_UNIT_LOW_NOISE_BYTE14;
// CRC
remote_state[15] = 0;
for (int i = 7; i < 15; i++) {
remote_state[15] += (byte) remote_state[i]; // Addiction
}
remote_state[15] = 0x100 - remote_state[15]; // mod 256
auto transmit = this->transmitter_->transmit();
auto data = transmit.get_data();
data->set_carrier_frequency(FUJITSU_GENERAL_CARRIER_FREQUENCY);
// Header
data->mark(FUJITSU_GENERAL_HEADER_MARK);
data->space(FUJITSU_GENERAL_HEADER_SPACE);
// Data
for (uint8_t i : remote_state) {
// Send all Bits from Byte Data in Reverse Order
for (uint8_t mask = 00000001; mask > 0; mask <<= 1) { // iterate through bit mask
data->mark(FUJITSU_GENERAL_BIT_MARK);
bool bit = i & mask;
data->space(bit ? FUJITSU_GENERAL_ONE_SPACE : FUJITSU_GENERAL_ZERO_SPACE);
// Next bits
}
}
// Footer
data->mark(FUJITSU_GENERAL_TRL_MARK);
data->space(FUJITSU_GENERAL_TRL_SPACE);
transmit.perform();
this->power_ = true;
}
void FujitsuGeneralClimate::transmit_off_() {
uint8_t remote_state[FUJITSU_GENERAL_OFF_LENGTH] = {0};
remote_state[0] = FUJITSU_GENERAL_OFF_BYTE0;
remote_state[1] = FUJITSU_GENERAL_OFF_BYTE1;
remote_state[2] = FUJITSU_GENERAL_OFF_BYTE2;
remote_state[3] = FUJITSU_GENERAL_OFF_BYTE3;
remote_state[4] = FUJITSU_GENERAL_OFF_BYTE4;
remote_state[5] = FUJITSU_GENERAL_OFF_BYTE5;
remote_state[6] = FUJITSU_GENERAL_OFF_BYTE6;
auto transmit = this->transmitter_->transmit();
auto data = transmit.get_data();
data->set_carrier_frequency(FUJITSU_GENERAL_CARRIER_FREQUENCY);
// Header
data->mark(FUJITSU_GENERAL_HEADER_MARK);
data->space(FUJITSU_GENERAL_HEADER_SPACE);
// Data
for (uint8_t i : remote_state) {
// Send all Bits from Byte Data in Reverse Order
for (uint8_t mask = 00000001; mask > 0; mask <<= 1) { // iterate through bit mask
data->mark(FUJITSU_GENERAL_BIT_MARK);
bool bit = i & mask;
data->space(bit ? FUJITSU_GENERAL_ONE_SPACE : FUJITSU_GENERAL_ZERO_SPACE);
// Next bits
}
}
// Footer
data->mark(FUJITSU_GENERAL_TRL_MARK);
data->space(FUJITSU_GENERAL_TRL_SPACE);
transmit.perform();
this->power_ = false;
}
} // namespace fujitsu_general
} // namespace esphome

View File

@@ -0,0 +1,24 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/automation.h"
#include "esphome/components/climate_ir/climate_ir.h"
namespace esphome {
namespace fujitsu_general {
class FujitsuGeneralClimate : public climate_ir::ClimateIR {
public:
FujitsuGeneralClimate();
protected:
/// Transmit via IR the state of this climate controller.
void transmit_state() override;
/// Transmit via IR power off command.
void transmit_off_();
bool power_{false};
};
} // namespace fujitsu_general
} // namespace esphome

View File

@@ -42,23 +42,24 @@ bool HX711Sensor::read_sensor_(uint32_t *result) {
this->status_clear_warning();
uint32_t data = 0;
disable_interrupts();
for (uint8_t i = 0; i < 24; i++) {
this->sck_pin_->digital_write(true);
delayMicroseconds(1);
data |= uint32_t(this->dout_pin_->digital_read()) << (23 - i);
this->sck_pin_->digital_write(false);
delayMicroseconds(1);
}
{
InterruptLock lock;
for (uint8_t i = 0; i < 24; i++) {
this->sck_pin_->digital_write(true);
delayMicroseconds(1);
data |= uint32_t(this->dout_pin_->digital_read()) << (23 - i);
this->sck_pin_->digital_write(false);
delayMicroseconds(1);
}
// Cycle clock pin for gain setting
for (uint8_t i = 0; i < this->gain_; i++) {
this->sck_pin_->digital_write(true);
delayMicroseconds(1);
this->sck_pin_->digital_write(false);
delayMicroseconds(1);
// Cycle clock pin for gain setting
for (uint8_t i = 0; i < this->gain_; i++) {
this->sck_pin_->digital_write(true);
delayMicroseconds(1);
this->sck_pin_->digital_write(false);
delayMicroseconds(1);
}
}
enable_interrupts();
if (data & 0x800000ULL) {
data |= 0xFF000000ULL;

View File

@@ -148,6 +148,11 @@ void LCDDisplay::printf(const char *format, ...) {
if (ret > 0)
this->print(0, 0, buffer);
}
void LCDDisplay::clear() {
// clear display, also sets DDRAM address to 0 (home)
this->command_(LCD_DISPLAY_COMMAND_CLEAR_DISPLAY);
delay(2);
}
#ifdef USE_TIME
void LCDDisplay::strftime(uint8_t column, uint8_t row, const char *format, time::ESPTime time) {
char buffer[64];

View File

@@ -23,6 +23,8 @@ class LCDDisplay : public PollingComponent {
float get_setup_priority() const override;
void update() override;
void display();
//// Clear LCD display
void clear();
/// Print the given text at the specified column and row.
void print(uint8_t column, uint8_t row, const char *str);

View File

@@ -42,8 +42,8 @@ float ledc_min_frequency_for_bit_depth(uint8_t bit_depth) {
}
optional<uint8_t> ledc_bit_depth_for_frequency(float frequency) {
for (int i = 20; i >= 1; i--) {
const float min_frequency = ledc_min_frequency_for_bit_depth(frequency);
const float max_frequency = ledc_max_frequency_for_bit_depth(frequency);
const float min_frequency = ledc_min_frequency_for_bit_depth(i);
const float max_frequency = ledc_max_frequency_for_bit_depth(i);
if (min_frequency <= frequency && frequency <= max_frequency)
return i;
}
@@ -56,7 +56,7 @@ void LEDCOutput::apply_frequency(float frequency) {
ESP_LOGW(TAG, "Frequency %f can't be achieved with any bit depth", frequency);
this->status_set_warning();
}
this->bit_depth_ = *bit_depth_opt;
this->bit_depth_ = bit_depth_opt.value_or(8);
this->frequency_ = frequency;
ledcSetup(this->channel_, frequency, this->bit_depth_);
// re-apply duty

View File

@@ -30,6 +30,8 @@ class Logger : public Component {
/// Manually set the baud rate for serial, set to 0 to disable.
void set_baud_rate(uint32_t baud_rate);
uint32_t get_baud_rate() const { return baud_rate_; }
HardwareSerial *get_hw_serial() const { return hw_serial_; }
/// Get the UART used by the logger.
UARTSelection get_uart() const;

View File

@@ -41,3 +41,4 @@ def register_modbus_device(var, config):
parent = yield cg.get_variable(config[CONF_MODBUS_ID])
cg.add(var.set_parent(parent))
cg.add(var.set_address(config[CONF_ADDRESS]))
cg.add(parent.register_device(var))

View File

@@ -24,7 +24,7 @@ void Modbus::loop() {
}
}
uint16_t crc16(uint8_t *data, uint8_t len) {
uint16_t crc16(const uint8_t *data, uint8_t len) {
uint16_t crc = 0xFFFF;
while (len--) {
crc ^= *data++;
@@ -43,7 +43,7 @@ uint16_t crc16(uint8_t *data, uint8_t len) {
bool Modbus::parse_modbus_byte_(uint8_t byte) {
size_t at = this->rx_buffer_.size();
this->rx_buffer_.push_back(byte);
uint8_t *raw = &this->rx_buffer_[0];
const uint8_t *raw = &this->rx_buffer_[0];
// Byte 0: modbus address (match all)
if (at == 0)
@@ -69,7 +69,7 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
return true;
// Byte 3+len+1: CRC_HI (over all bytes)
uint16_t computed_crc = crc16(raw, 3 + data_len);
uint16_t remote_crc = uint16_t(raw[3 + data_len]) | (uint16_t(raw[3 + data_len]) << 8);
uint16_t remote_crc = uint16_t(raw[3 + data_len]) | (uint16_t(raw[3 + data_len + 1]) << 8);
if (computed_crc != remote_crc) {
ESP_LOGW(TAG, "Modbus CRC Check failed! %02X!=%02X", computed_crc, remote_crc);
return false;

View File

@@ -10,7 +10,7 @@ void MPR121Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up MPR121...");
// soft reset device
this->write_byte(MPR121_SOFTRESET, 0x63);
delay(100);
delay(100); // NOLINT
if (!this->write_byte(MPR121_ECR, 0x0)) {
this->error_code_ = COMMUNICATION_FAILED;
this->mark_failed();

View File

@@ -155,7 +155,7 @@ def to_code(config):
yield cg.register_component(var, config)
# https://github.com/OttoWinter/async-mqtt-client/blob/master/library.json
cg.add_library('AsyncMqttClient-esphome', '0.8.3')
cg.add_library('AsyncMqttClient-esphome', '0.8.4')
cg.add_define('USE_MQTT')
cg.add_global(mqtt_ns.using)

View File

@@ -201,7 +201,7 @@ void MQTTClientComponent::check_connected() {
this->status_clear_warning();
ESP_LOGI(TAG, "MQTT Connected!");
// MQTT Client needs some time to be fully set up.
delay(100);
delay(100); // NOLINT
this->resubscribe_subscriptions_();

View File

@@ -55,6 +55,9 @@ void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo
if (!this->sensor_->get_icon().empty())
root["icon"] = this->sensor_->get_icon();
if (this->sensor_->get_force_update())
root["force_update"] = true;
config.command_topic = false;
}
bool MQTTSensorComponent::send_initial_state() {

View File

@@ -19,7 +19,7 @@ void MS5611Component::setup() {
this->mark_failed();
return;
}
delay(100);
delay(100); // NOLINT
for (uint8_t offset = 0; offset < 6; offset++) {
if (!this->read_byte_16(MS5611_CMD_READ_PROM + (offset * 2), &this->prom_[offset])) {
this->mark_failed();

View File

@@ -74,7 +74,11 @@ def validate_method_pin(value):
method_pins['BIT_BANG'] = list(range(0, 16))
elif CORE.is_esp32:
method_pins['BIT_BANG'] = list(range(0, 32))
pins_ = method_pins[method]
pins_ = method_pins.get(method)
if pins_ is None:
# all pins allowed for this method
return value
for opt in (CONF_PIN, CONF_CLOCK_PIN, CONF_DATA_PIN):
if opt in value and value[opt] not in pins_:
raise cv.Invalid("Method {} only supports pin(s) {}".format(

View File

@@ -394,7 +394,7 @@ class Nextion : public PollingComponent, public uart::UARTDevice {
bool wait_for_ack_{true};
};
class NextionTouchComponent : public binary_sensor::BinarySensor {
class NextionTouchComponent : public binary_sensor::BinarySensorInitiallyOff {
public:
void set_page_id(uint8_t page_id) { page_id_ = page_id; }
void set_component_id(uint8_t component_id) { component_id_ = component_id; }

View File

@@ -19,9 +19,9 @@ void NTC::process_(float value) {
return;
}
float lr = logf(value);
float v = this->a_ + this->b_ * lr + this->c_ * lr * lr * lr;
float temp = 1 / v - 273.15f;
double lr = log(double(value));
double v = this->a_ + this->b_ * lr + this->c_ * lr * lr * lr;
auto temp = float(1.0 / v - 273.15);
ESP_LOGD(TAG, "'%s' - Temperature: %.1f°C", this->name_.c_str(), temp);
this->publish_state(temp);

View File

@@ -9,9 +9,9 @@ namespace ntc {
class NTC : public Component, public sensor::Sensor {
public:
void set_sensor(Sensor *sensor) { sensor_ = sensor; }
void set_a(float a) { a_ = a; }
void set_b(float b) { b_ = b; }
void set_c(float c) { c_ = c; }
void set_a(double a) { a_ = a; }
void set_b(double b) { b_ = b; }
void set_c(double c) { c_ = c; }
void setup() override;
void dump_config() override;
float get_setup_priority() const override;
@@ -20,9 +20,9 @@ class NTC : public Component, public sensor::Sensor {
void process_(float value);
sensor::Sensor *sensor_;
float a_;
float b_;
float c_;
double a_;
double b_;
double c_;
};
} // namespace ntc

View File

@@ -266,7 +266,7 @@ void OTAComponent::handle_() {
delay(10);
ESP_LOGI(TAG, "OTA update finished!");
this->status_clear_warning();
delay(100);
delay(100); // NOLINT
App.safe_reboot();
error:

View File

@@ -11,7 +11,6 @@ pcf8574_ns = cg.esphome_ns.namespace('pcf8574')
PCF8574GPIOMode = pcf8574_ns.enum('PCF8574GPIOMode')
PCF8674_GPIO_MODES = {
'INPUT': PCF8574GPIOMode.PCF8574_INPUT,
'INPUT_PULLUP': PCF8574GPIOMode.PCF8574_INPUT_PULLUP,
'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT,
}
@@ -33,16 +32,24 @@ def to_code(config):
cg.add(var.set_pcf8575(config[CONF_PCF8575]))
def validate_pcf8574_gpio_mode(value):
value = cv.string(value)
if value.upper() == 'INPUT_PULLUP':
raise cv.Invalid("INPUT_PULLUP mode has been removed in 1.14 and been combined into "
"INPUT mode (they were the same thing). Please use INPUT instead.")
return cv.enum(PCF8674_GPIO_MODES, upper=True)(value)
PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
cv.Required(CONF_NUMBER): cv.int_,
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(PCF8674_GPIO_MODES, upper=True),
cv.Optional(CONF_MODE, default="OUTPUT"): validate_pcf8574_gpio_mode,
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
})
PCF8574_INPUT_PIN_SCHEMA = cv.Schema({
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
cv.Required(CONF_NUMBER): cv.int_,
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(PCF8674_GPIO_MODES, upper=True),
cv.Optional(CONF_MODE, default="INPUT"): validate_pcf8574_gpio_mode,
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
})

View File

@@ -31,9 +31,9 @@ bool PCF8574Component::digital_read(uint8_t pin) {
}
void PCF8574Component::digital_write(uint8_t pin, bool value) {
if (value) {
this->port_mask_ |= (1 << pin);
this->output_mask_ |= (1 << pin);
} else {
this->port_mask_ &= ~(1 << pin);
this->output_mask_ &= ~(1 << pin);
}
this->write_gpio_();
@@ -41,16 +41,14 @@ void PCF8574Component::digital_write(uint8_t pin, bool value) {
void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {
switch (mode) {
case PCF8574_INPUT:
this->ddr_mask_ &= ~(1 << pin);
this->port_mask_ &= ~(1 << pin);
break;
case PCF8574_INPUT_PULLUP:
this->ddr_mask_ &= ~(1 << pin);
this->port_mask_ |= (1 << pin);
// Clear mode mask bit
this->mode_mask_ &= ~(1 << pin);
// Write GPIO to enable input mode
this->write_gpio_();
break;
case PCF8574_OUTPUT:
this->ddr_mask_ |= (1 << pin);
this->port_mask_ &= ~(1 << pin);
// Set mode mask bit
this->mode_mask_ |= 1 << pin;
break;
default:
break;
@@ -59,21 +57,20 @@ void PCF8574Component::pin_mode(uint8_t pin, uint8_t mode) {
bool PCF8574Component::read_gpio_() {
if (this->is_failed())
return false;
bool success;
uint8_t data[2];
if (this->pcf8575_) {
if (!this->parent_->raw_receive_16(this->address_, &this->input_mask_, 1)) {
this->status_set_warning();
return false;
}
success = this->read_bytes_raw(data, 2);
this->input_mask_ = (uint16_t(data[1]) << 8) | (uint16_t(data[0]) << 0);
} else {
uint8_t data;
if (!this->parent_->raw_receive(this->address_, &data, 1)) {
this->status_set_warning();
return false;
}
this->input_mask_ = data;
success = this->read_bytes_raw(data, 1);
this->input_mask_ = data[0];
}
if (!success) {
this->status_set_warning();
return false;
}
this->status_clear_warning();
return true;
}
@@ -81,20 +78,20 @@ bool PCF8574Component::write_gpio_() {
if (this->is_failed())
return false;
uint16_t value = (this->input_mask_ & ~this->ddr_mask_) | this->port_mask_;
uint16_t value = 0;
// Pins in OUTPUT mode and where pin is HIGH.
value |= this->mode_mask_ & this->output_mask_;
// Pins in INPUT mode must also be set here
value |= ~this->mode_mask_;
this->parent_->raw_begin_transmission(this->address_);
uint8_t data = value & 0xFF;
this->parent_->raw_write(this->address_, &data, 1);
if (this->pcf8575_) {
data = (value >> 8) & 0xFF;
this->parent_->raw_write(this->address_, &data, 1);
}
if (!this->parent_->raw_end_transmission(this->address_)) {
uint8_t data[2];
data[0] = value;
data[1] = value >> 8;
if (!this->write_bytes_raw(data, this->pcf8575_ ? 2 : 1)) {
this->status_set_warning();
return false;
}
this->status_clear_warning();
return true;
}

View File

@@ -10,7 +10,6 @@ namespace pcf8574 {
/// Modes for PCF8574 pins
enum PCF8574GPIOMode : uint8_t {
PCF8574_INPUT = INPUT,
PCF8574_INPUT_PULLUP = INPUT_PULLUP,
PCF8574_OUTPUT = OUTPUT,
};
@@ -38,9 +37,12 @@ class PCF8574Component : public Component, public i2c::I2CDevice {
bool write_gpio_();
uint16_t ddr_mask_{0x00};
/// Mask for the pin mode - 1 means output, 0 means input
uint16_t mode_mask_{0x00};
/// The mask to write as output state - 1 means HIGH, 0 means LOW
uint16_t output_mask_{0x00};
/// The state read in read_gpio_ - 1 means HIGH, 0 means LOW
uint16_t input_mask_{0x00};
uint16_t port_mask_{0x00};
bool pcf8575_; ///< TRUE->16-channel PCF8575, FALSE->8-channel PCF8574
};

View File

@@ -12,24 +12,24 @@ pmsx003_ns = cg.esphome_ns.namespace('pmsx003')
PMSX003Component = pmsx003_ns.class_('PMSX003Component', uart.UARTDevice, cg.Component)
PMSX003Sensor = pmsx003_ns.class_('PMSX003Sensor', sensor.Sensor)
CONF_PMSX003 = 'PMSX003'
CONF_PMS5003T = 'PMS5003T'
CONF_PMS5003ST = 'PMS5003ST'
TYPE_PMSX003 = 'PMSX003'
TYPE_PMS5003T = 'PMS5003T'
TYPE_PMS5003ST = 'PMS5003ST'
PMSX003Type = pmsx003_ns.enum('PMSX003Type')
PMSX003_TYPES = {
CONF_PMSX003: PMSX003Type.PMSX003_TYPE_X003,
CONF_PMS5003T: PMSX003Type.PMSX003_TYPE_5003T,
CONF_PMS5003ST: PMSX003Type.PMSX003_TYPE_5003ST,
TYPE_PMSX003: PMSX003Type.PMSX003_TYPE_X003,
TYPE_PMS5003T: PMSX003Type.PMSX003_TYPE_5003T,
TYPE_PMS5003ST: PMSX003Type.PMSX003_TYPE_5003ST,
}
SENSORS_TO_TYPE = {
CONF_PM_1_0: [CONF_PMSX003, CONF_PMS5003ST],
CONF_PM_2_5: [CONF_PMSX003, CONF_PMS5003T, CONF_PMS5003ST],
CONF_PM_10_0: [CONF_PMSX003, CONF_PMS5003ST],
CONF_TEMPERATURE: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_HUMIDITY: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_FORMALDEHYDE: [CONF_PMS5003ST],
CONF_PM_1_0: [TYPE_PMSX003, TYPE_PMS5003ST],
CONF_PM_2_5: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST],
CONF_PM_10_0: [TYPE_PMSX003, TYPE_PMS5003ST],
CONF_TEMPERATURE: [TYPE_PMS5003T, TYPE_PMS5003ST],
CONF_HUMIDITY: [TYPE_PMS5003T, TYPE_PMS5003ST],
CONF_FORMALDEHYDE: [TYPE_PMS5003ST],
}

View File

@@ -149,6 +149,7 @@ void PulseCounterSensor::dump_config() {
ESP_LOGCONFIG(TAG, " Rising Edge: %s", EDGE_MODE_TO_STRING[this->storage_.rising_edge_mode]);
ESP_LOGCONFIG(TAG, " Falling Edge: %s", EDGE_MODE_TO_STRING[this->storage_.falling_edge_mode]);
ESP_LOGCONFIG(TAG, " Filtering pulses shorter than %u µs", this->storage_.filter_us);
LOG_UPDATE_INTERVAL(this);
}
void PulseCounterSensor::update() {

View File

@@ -8,7 +8,7 @@ static const char *TAG = "pzem004t";
void PZEM004T::loop() {
const uint32_t now = millis();
if (now - this->last_read_ > 500 && this->available()) {
if (now - this->last_read_ > 500 && this->available() < 7) {
while (this->available())
this->read();
this->last_read_ = now;
@@ -78,7 +78,7 @@ void PZEM004T::loop() {
this->last_read_ = now;
}
}
void PZEM004T::update() { this->write_state_(SET_ADDRESS); }
void PZEM004T::update() { this->write_state_(READ_VOLTAGE); }
void PZEM004T::write_state_(PZEM004T::PZEM004TReadState state) {
if (state == DONE) {
this->read_state_ = state;
@@ -98,6 +98,12 @@ void PZEM004T::write_state_(PZEM004T::PZEM004TReadState state) {
this->write_array(data);
this->read_state_ = state;
}
void PZEM004T::dump_config() {
ESP_LOGCONFIG(TAG, "PZEM004T:");
LOG_SENSOR("", "Voltage", this->voltage_sensor_);
LOG_SENSOR("", "Current", this->current_sensor_);
LOG_SENSOR("", "Power", this->power_sensor_);
}
} // namespace pzem004t
} // namespace esphome

View File

@@ -17,6 +17,8 @@ class PZEM004T : public PollingComponent, public uart::UARTDevice {
void update() override;
void dump_config() override;
protected:
sensor::Sensor *voltage_sensor_;
sensor::Sensor *current_sensor_;

View File

@@ -57,6 +57,15 @@ void PZEMAC::on_modbus_data(const std::vector<uint8_t> &data) {
}
void PZEMAC::update() { this->send(PZEM_CMD_READ_IN_REGISTERS, 0, PZEM_REGISTER_COUNT); }
void PZEMAC::dump_config() {
ESP_LOGCONFIG(TAG, "PZEMAC:");
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
LOG_SENSOR("", "Voltage", this->voltage_sensor_);
LOG_SENSOR("", "Current", this->current_sensor_);
LOG_SENSOR("", "Power", this->power_sensor_);
LOG_SENSOR("", "Frequency", this->frequency_sensor_);
LOG_SENSOR("", "Power Factor", this->power_factor_sensor_);
}
} // namespace pzemac
} // namespace esphome

View File

@@ -19,6 +19,8 @@ class PZEMAC : public PollingComponent, public modbus::ModbusDevice {
void on_modbus_data(const std::vector<uint8_t> &data) override;
void dump_config() override;
protected:
sensor::Sensor *voltage_sensor_;
sensor::Sensor *current_sensor_;

View File

@@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome.components import sensor, modbus
from esphome.const import CONF_CURRENT, CONF_ID, CONF_POWER, CONF_VOLTAGE, \
CONF_FREQUENCY, UNIT_VOLT, ICON_FLASH, UNIT_AMPERE, UNIT_WATT, UNIT_EMPTY, \
ICON_POWER, CONF_POWER_FACTOR, ICON_CURRENT_AC
ICON_POWER, CONF_POWER_FACTOR, ICON_CURRENT_AC, UNIT_HERTZ
AUTO_LOAD = ['modbus']
@@ -15,7 +15,7 @@ CONFIG_SCHEMA = cv.Schema({
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_FLASH, 1),
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_CURRENT_AC, 3),
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_POWER, 1),
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(UNIT_EMPTY, ICON_CURRENT_AC, 1),
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(UNIT_HERTZ, ICON_CURRENT_AC, 1),
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(UNIT_EMPTY, ICON_FLASH, 2),
}).extend(cv.polling_component_schema('60s')).extend(modbus.modbus_device_schema(0x01))

View File

@@ -47,6 +47,13 @@ void PZEMDC::on_modbus_data(const std::vector<uint8_t> &data) {
}
void PZEMDC::update() { this->send(PZEM_CMD_READ_IN_REGISTERS, 0, 8); }
void PZEMDC::dump_config() {
ESP_LOGCONFIG(TAG, "PZEMDC:");
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
LOG_SENSOR("", "Voltage", this->voltage_sensor_);
LOG_SENSOR("", "Current", this->current_sensor_);
LOG_SENSOR("", "Power", this->power_sensor_);
}
} // namespace pzemdc
} // namespace esphome

View File

@@ -19,6 +19,8 @@ class PZEMDC : public PollingComponent, public modbus::ModbusDevice {
void on_modbus_data(const std::vector<uint8_t> &data) override;
void dump_config() override;
protected:
sensor::Sensor *voltage_sensor_;
sensor::Sensor *current_sensor_;

View File

@@ -28,7 +28,7 @@ class RDM6300Component : public Component, public uart::UARTDevice {
uint32_t last_id_{0};
};
class RDM6300BinarySensor : public binary_sensor::BinarySensor {
class RDM6300BinarySensor : public binary_sensor::BinarySensorInitiallyOff {
public:
void set_id(uint32_t id) { id_ = id; }

View File

@@ -267,11 +267,11 @@ class RemoteReceiverBase : public RemoteComponentBase {
uint8_t tolerance_{25};
};
class RemoteReceiverBinarySensorBase : public binary_sensor::BinarySensor,
class RemoteReceiverBinarySensorBase : public binary_sensor::BinarySensorInitiallyOff,
public Component,
public RemoteReceiverListener {
public:
explicit RemoteReceiverBinarySensorBase() : BinarySensor() {}
explicit RemoteReceiverBinarySensorBase() : BinarySensorInitiallyOff() {}
void dump_config() override;
virtual bool matches(RemoteReceiveData src) = 0;
bool on_receive(RemoteReceiveData src) override {

View File

@@ -67,22 +67,22 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
uint32_t on_time, off_time;
this->calculate_on_off_time_(this->temp_.get_carrier_frequency(), &on_time, &off_time);
for (uint32_t i = 0; i < send_times; i++) {
disable_interrupts();
for (int32_t item : this->temp_.get_data()) {
if (item > 0) {
const auto length = uint32_t(item);
this->mark_(on_time, off_time, length);
} else {
const auto length = uint32_t(-item);
this->space_(length);
{
InterruptLock lock;
for (int32_t item : this->temp_.get_data()) {
if (item > 0) {
const auto length = uint32_t(item);
this->mark_(on_time, off_time, length);
} else {
const auto length = uint32_t(-item);
this->space_(length);
}
App.feed_wdt();
}
App.feed_wdt();
}
enable_interrupts();
if (i + 1 < send_times) {
delay(send_wait / 1000UL);
delayMicroseconds(send_wait % 1000UL);
delay_microseconds_accurate(send_wait);
}
}
}

View File

@@ -13,8 +13,8 @@ void RestartSwitch::write_state(bool state) {
if (state) {
ESP_LOGI(TAG, "Restarting device...");
// then execute
delay(100); // Let MQTT settle a bit
// Let MQTT settle a bit
delay(100); // NOLINT
App.safe_reboot();
}
}

View File

@@ -32,7 +32,13 @@ static const uint16_t STATE_DECREMENT_COUNTER_1 = 0x1000;
// Bit 2&3 (0x0C) encodes state S0-S3
// Bit 4 (0x10) encodes clockwise/counter-clockwise rotation
static const uint16_t STATE_LOOKUP_TABLE[32] = {
// Only apply if DRAM_ATTR exists on this platform (exists on ESP32, not on ESP8266)
#ifndef DRAM_ATTR
#define DRAM_ATTR
#endif
// array needs to be placed in .dram1 for ESP32
// otherwise it will automatically go into flash, and cause cache disabled issues
static const uint16_t DRAM_ATTR STATE_LOOKUP_TABLE[32] = {
// act state S0 in CCW direction
STATE_CCW | STATE_S0, // 0x00: stay here
STATE_CW | STATE_S1 | STATE_INCREMENT_COUNTER_1, // 0x01: goto CW+S1 and increment counter (dir change)

View File

@@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome import pins, automation
from esphome.components import sensor
from esphome.const import CONF_ID, CONF_RESOLUTION, CONF_MIN_VALUE, CONF_MAX_VALUE, UNIT_STEPS, \
ICON_ROTATE_RIGHT, CONF_VALUE
ICON_ROTATE_RIGHT, CONF_VALUE, CONF_PIN_A, CONF_PIN_B
rotary_encoder_ns = cg.esphome_ns.namespace('rotary_encoder')
RotaryEncoderResolution = rotary_encoder_ns.enum('RotaryEncoderResolution')
@@ -13,8 +13,6 @@ RESOLUTIONS = {
4: RotaryEncoderResolution.ROTARY_ENCODER_4_PULSES_PER_CYCLE,
}
CONF_PIN_A = 'pin_a'
CONF_PIN_B = 'pin_b'
CONF_PIN_RESET = 'pin_reset'
RotaryEncoderSensor = rotary_encoder_ns.class_('RotaryEncoderSensor', sensor.Sensor, cg.Component)

View File

@@ -3,15 +3,13 @@ import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import CONF_ID, UNIT_PARTS_PER_MILLION, \
CONF_HUMIDITY, CONF_TEMPERATURE, ICON_PERIODIC_TABLE_CO2, \
UNIT_CELSIUS, ICON_THERMOMETER, ICON_WATER_PERCENT, UNIT_PERCENT
UNIT_CELSIUS, ICON_THERMOMETER, ICON_WATER_PERCENT, UNIT_PERCENT, CONF_CO2
DEPENDENCIES = ['i2c']
scd30_ns = cg.esphome_ns.namespace('scd30')
SCD30Component = scd30_ns.class_('SCD30Component', cg.PollingComponent, i2c.I2CDevice)
CONF_CO2 = 'co2'
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(SCD30Component),
cv.Required(CONF_CO2): sensor.sensor_schema(UNIT_PARTS_PER_MILLION,

View File

@@ -6,10 +6,9 @@ from esphome import automation
from esphome.components import mqtt
from esphome.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
CONF_EXPIRE_AFTER, CONF_FILTERS, CONF_FROM, CONF_ICON, CONF_ID, CONF_INTERNAL, \
CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, \
CONF_SEND_EVERY, CONF_SEND_FIRST_AT, CONF_TO, CONF_TRIGGER_ID, \
CONF_UNIT_OF_MEASUREMENT, \
CONF_WINDOW_SIZE, CONF_NAME, CONF_MQTT_ID
CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, CONF_SEND_EVERY, CONF_SEND_FIRST_AT, \
CONF_TO, CONF_TRIGGER_ID, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE, CONF_NAME, CONF_MQTT_ID, \
CONF_FORCE_UPDATE
from esphome.core import CORE, coroutine, coroutine_with_priority
from esphome.util import Registry
@@ -87,6 +86,7 @@ SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
cv.Optional(CONF_UNIT_OF_MEASUREMENT): unit_of_measurement,
cv.Optional(CONF_ICON): icon,
cv.Optional(CONF_ACCURACY_DECIMALS): accuracy_decimals,
cv.Optional(CONF_FORCE_UPDATE, default=False): cv.boolean,
cv.Optional(CONF_EXPIRE_AFTER): cv.All(cv.requires_component('mqtt'),
cv.Any(None, cv.positive_time_period_milliseconds)),
cv.Optional(CONF_FILTERS): validate_filters,
@@ -258,7 +258,8 @@ def setup_sensor_core_(var, config):
cg.add(var.set_icon(config[CONF_ICON]))
if CONF_ACCURACY_DECIMALS in config:
cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
if CONF_FILTERS in config:
cg.add(var.set_force_update(config[CONF_FORCE_UPDATE]))
if config.get(CONF_FILTERS): # must exist and not be empty
filters = yield build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))

View File

@@ -9,14 +9,17 @@ namespace sensor {
#define LOG_SENSOR(prefix, type, obj) \
if (obj != nullptr) { \
ESP_LOGCONFIG(TAG, prefix type " '%s'", obj->get_name().c_str()); \
ESP_LOGCONFIG(TAG, prefix " Unit of Measurement: '%s'", obj->get_unit_of_measurement().c_str()); \
ESP_LOGCONFIG(TAG, prefix " Accuracy Decimals: %d", obj->get_accuracy_decimals()); \
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, type, obj->get_name().c_str()); \
ESP_LOGCONFIG(TAG, "%s Unit of Measurement: '%s'", prefix, obj->get_unit_of_measurement().c_str()); \
ESP_LOGCONFIG(TAG, "%s Accuracy Decimals: %d", prefix, obj->get_accuracy_decimals()); \
if (!obj->get_icon().empty()) { \
ESP_LOGCONFIG(TAG, prefix " Icon: '%s'", obj->get_icon().c_str()); \
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, obj->get_icon().c_str()); \
} \
if (!obj->unique_id().empty()) { \
ESP_LOGV(TAG, prefix " Unique ID: '%s'", obj->unique_id().c_str()); \
ESP_LOGV(TAG, "%s Unique ID: '%s'", prefix, obj->unique_id().c_str()); \
} \
if (obj->get_force_update()) { \
ESP_LOGV(TAG, "%s Force Update: YES", prefix); \
} \
}
@@ -142,6 +145,15 @@ class Sensor : public Nameable {
void internal_send_state_to_frontend(float state);
bool get_force_update() const { return force_update_; }
/** Set this sensor's force_update mode.
*
* If the sensor is in force_update mode, the frontend is required to save all
* state changes to the database when they are published, even if the state is the
* same as before.
*/
void set_force_update(bool force_update) { force_update_ = force_update; }
protected:
/** Override this to set the Home Assistant unit of measurement for this sensor.
*
@@ -174,6 +186,7 @@ class Sensor : public Nameable {
optional<int8_t> accuracy_decimals_;
Filter *filter_list_{nullptr}; ///< Store all active filters.
bool has_state_{false};
bool force_update_{false};
};
class PollingSensorComponent : public PollingComponent, public Sensor {

View File

@@ -4,7 +4,7 @@ from esphome import automation
from esphome.automation import maybe_simple_id
from esphome.components.output import FloatOutput
from esphome.const import CONF_ID, CONF_IDLE_LEVEL, CONF_MAX_LEVEL, CONF_MIN_LEVEL, CONF_OUTPUT, \
CONF_LEVEL
CONF_LEVEL, CONF_RESTORE
servo_ns = cg.esphome_ns.namespace('servo')
Servo = servo_ns.class_('Servo', cg.Component)
@@ -18,6 +18,7 @@ CONFIG_SCHEMA = cv.Schema({
cv.Optional(CONF_MIN_LEVEL, default='3%'): cv.percentage,
cv.Optional(CONF_IDLE_LEVEL, default='7.5%'): cv.percentage,
cv.Optional(CONF_MAX_LEVEL, default='12%'): cv.percentage,
cv.Optional(CONF_RESTORE, default=False): cv.boolean,
}).extend(cv.COMPONENT_SCHEMA)
@@ -30,6 +31,7 @@ def to_code(config):
cg.add(var.set_min_level(config[CONF_MIN_LEVEL]))
cg.add(var.set_idle_level(config[CONF_IDLE_LEVEL]))
cg.add(var.set_max_level(config[CONF_MAX_LEVEL]))
cg.add(var.set_restore(config[CONF_RESTORE]))
@automation.register_action('servo.write', ServoWriteAction, cv.Schema({

View File

@@ -47,6 +47,7 @@ class Servo : public Component {
void set_min_level(float min_level) { min_level_ = min_level; }
void set_idle_level(float idle_level) { idle_level_ = idle_level; }
void set_max_level(float max_level) { max_level_ = max_level; }
void set_restore(bool restore) { restore_ = restore; }
protected:
void save_level_(float v) { this->rtc_.save(&v); }

View File

@@ -14,8 +14,8 @@ CONF_TVOC = 'tvoc'
CONF_BASELINE = 'baseline'
CONF_UPTIME = 'uptime'
CONF_COMPENSATION = 'compensation'
CONF_COMPENSATION_HUMIDITY = 'humidity_source'
CONF_COMPENSATION_TEMPERATURE = 'temperature_source'
CONF_HUMIDITY_SOURCE = 'humidity_source'
CONF_TEMPERATURE_SOURCE = 'temperature_source'
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(SGP30Component),
@@ -24,8 +24,8 @@ CONFIG_SCHEMA = cv.Schema({
cv.Required(CONF_TVOC): sensor.sensor_schema(UNIT_PARTS_PER_BILLION, ICON_RADIATOR, 0),
cv.Optional(CONF_BASELINE): cv.hex_uint16_t,
cv.Optional(CONF_COMPENSATION): cv.Schema({
cv.Required(CONF_COMPENSATION_HUMIDITY): cv.use_id(sensor.Sensor),
cv.Required(CONF_COMPENSATION_TEMPERATURE): cv.use_id(sensor.Sensor)
cv.Required(CONF_HUMIDITY_SOURCE): cv.use_id(sensor.Sensor),
cv.Required(CONF_TEMPERATURE_SOURCE): cv.use_id(sensor.Sensor)
}),
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x58))
@@ -48,7 +48,7 @@ def to_code(config):
if CONF_COMPENSATION in config:
compensation_config = config[CONF_COMPENSATION]
sens = yield cg.get_variable(compensation_config[CONF_COMPENSATION_HUMIDITY])
sens = yield cg.get_variable(compensation_config[CONF_HUMIDITY_SOURCE])
cg.add(var.set_humidity_sensor(sens))
sens = yield cg.get_variable(compensation_config[CONF_COMPENSATION_TEMPERATURE])
sens = yield cg.get_variable(compensation_config[CONF_TEMPERATURE_SOURCE])
cg.add(var.set_temperature_sensor(sens))

View File

@@ -14,7 +14,7 @@ void ShutdownSwitch::write_state(bool state) {
if (state) {
ESP_LOGI(TAG, "Shutting down...");
delay(100); // Let MQTT settle a bit
delay(100); // NOLINT
App.run_safe_shutdown_hooks();
#ifdef ARDUINO_ARCH_ESP8266

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