mirror of
https://github.com/esphome/esphome.git
synced 2025-11-02 16:11:53 +00:00
Compare commits
77 Commits
jesserockz
...
2023.8.0b3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f44e5d3142 | ||
|
|
532163738e | ||
|
|
63fa922547 | ||
|
|
48e4cb5ae2 | ||
|
|
ff8a73c2d1 | ||
|
|
afd26c6f1a | ||
|
|
67b06a88b2 | ||
|
|
265e019381 | ||
|
|
560e36a65c | ||
|
|
b05a3fbb55 | ||
|
|
3a899e28dc | ||
|
|
f26238e824 | ||
|
|
3717e34bba | ||
|
|
be6f95d43e | ||
|
|
99a765dc06 | ||
|
|
351e7ea16b | ||
|
|
2fa79a2e2f | ||
|
|
44a917929d | ||
|
|
21ebc7f95b | ||
|
|
72e72d7d4b | ||
|
|
02ed2c0ebe | ||
|
|
0f506ea8eb | ||
|
|
b914d6e305 | ||
|
|
956e19be7d | ||
|
|
b3d5a4dfdb | ||
|
|
c63cdae84f | ||
|
|
dec044ad8b | ||
|
|
2a12ec09fb | ||
|
|
91e920c498 | ||
|
|
9b19c45735 | ||
|
|
3843d21dbf | ||
|
|
73db164fb1 | ||
|
|
ab32dd7420 | ||
|
|
2a7aa2fc0d | ||
|
|
f5e98eb86f | ||
|
|
362a19c2e1 | ||
|
|
f4a4956dd4 | ||
|
|
746488cabf | ||
|
|
4449248c6f | ||
|
|
036e14ab7f | ||
|
|
f840eee1b7 | ||
|
|
553132443f | ||
|
|
d20242f589 | ||
|
|
68affce274 | ||
|
|
c4b9065749 | ||
|
|
d57a5d1793 | ||
|
|
74e062fdb3 | ||
|
|
6bdc0c92fe | ||
|
|
d7945de001 | ||
|
|
3ba2a29e54 | ||
|
|
76b438f79c | ||
|
|
bc14f06a07 | ||
|
|
feee075122 | ||
|
|
a77cf1beec | ||
|
|
d7bfdd0efc | ||
|
|
62aee36f82 | ||
|
|
0709367587 | ||
|
|
98277f6ceb | ||
|
|
8dd509ba53 | ||
|
|
8df455f55b | ||
|
|
36782f13bf | ||
|
|
e823067a6b | ||
|
|
c3ef12d580 | ||
|
|
321155eb40 | ||
|
|
d34c074b92 | ||
|
|
abc8e903c1 | ||
|
|
832ba38f1b | ||
|
|
70de2f5278 | ||
|
|
604d4eec79 | ||
|
|
b806eb6a61 | ||
|
|
39948db59a | ||
|
|
fbfb4e2a73 | ||
|
|
595ac84779 | ||
|
|
746f72a279 | ||
|
|
dec6f04499 | ||
|
|
a90d266017 | ||
|
|
df9fcf9850 |
10
CODEOWNERS
10
CODEOWNERS
@@ -54,7 +54,7 @@ esphome/components/bp1658cj/* @Cossid
|
||||
esphome/components/bp5758d/* @Cossid
|
||||
esphome/components/button/* @esphome/core
|
||||
esphome/components/canbus/* @danielschramm @mvturnho
|
||||
esphome/components/cap1188/* @mreditor97
|
||||
esphome/components/cap1188/* @MrEditor97
|
||||
esphome/components/captive_portal/* @OttoWinter
|
||||
esphome/components/ccs811/* @habbie
|
||||
esphome/components/cd74hc4067/* @asoehlke
|
||||
@@ -87,13 +87,12 @@ esphome/components/ens210/* @itn3rd77
|
||||
esphome/components/esp32/* @esphome/core
|
||||
esphome/components/esp32_ble/* @jesserockz
|
||||
esphome/components/esp32_ble_client/* @jesserockz
|
||||
esphome/components/esp32_ble_server/* @clydebarrow @jesserockz
|
||||
esphome/components/esp32_ble_server/* @jesserockz
|
||||
esphome/components/esp32_camera_web_server/* @ayufan
|
||||
esphome/components/esp32_can/* @Sympatron
|
||||
esphome/components/esp32_improv/* @jesserockz
|
||||
esphome/components/esp32_rmt_led_strip/* @jesserockz
|
||||
esphome/components/esp8266/* @esphome/core
|
||||
esphome/components/esp_adf/* @jesserockz
|
||||
esphome/components/ethernet_info/* @gtjadsonsantos
|
||||
esphome/components/exposure_notifications/* @OttoWinter
|
||||
esphome/components/ezo/* @ssieb
|
||||
@@ -133,7 +132,7 @@ esphome/components/i2s_audio/speaker/* @jesserockz
|
||||
esphome/components/ili9xxx/* @nielsnl68
|
||||
esphome/components/improv_base/* @esphome/core
|
||||
esphome/components/improv_serial/* @esphome/core
|
||||
esphome/components/ina260/* @mreditor97
|
||||
esphome/components/ina260/* @MrEditor97
|
||||
esphome/components/inkbird_ibsth1_mini/* @fkirill
|
||||
esphome/components/inkplate6/* @jesserockz
|
||||
esphome/components/integration/* @OttoWinter
|
||||
@@ -169,7 +168,7 @@ esphome/components/mcp2515/* @danielschramm @mvturnho
|
||||
esphome/components/mcp3204/* @rsumner
|
||||
esphome/components/mcp4728/* @berfenger
|
||||
esphome/components/mcp47a1/* @jesserockz
|
||||
esphome/components/mcp9600/* @mreditor97
|
||||
esphome/components/mcp9600/* @MrEditor97
|
||||
esphome/components/mcp9808/* @k7hpn
|
||||
esphome/components/md5/* @esphome/core
|
||||
esphome/components/mdns/* @esphome/core
|
||||
@@ -213,7 +212,6 @@ esphome/components/pid/* @OttoWinter
|
||||
esphome/components/pipsolar/* @andreashergert1984
|
||||
esphome/components/pm1006/* @habbie
|
||||
esphome/components/pmsa003i/* @sjtrny
|
||||
esphome/components/pmwcs3/* @SeByDocKy
|
||||
esphome/components/pn532/* @OttoWinter @jesserockz
|
||||
esphome/components/pn532_i2c/* @OttoWinter @jesserockz
|
||||
esphome/components/pn532_spi/* @OttoWinter @jesserockz
|
||||
|
||||
@@ -28,15 +28,14 @@ RUN \
|
||||
git=1:2.30.2-1+deb11u2 \
|
||||
curl=7.74.0-1.3+deb11u7 \
|
||||
openssh-client=1:8.4p1-5+deb11u1 \
|
||||
python3-cffi=1.14.5-1 \
|
||||
libcairo2=1.16.0-5; \
|
||||
python3-cffi=1.14.5-1; \
|
||||
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential=12.9 \
|
||||
python3-dev=3.9.2-3 \
|
||||
zlib1g-dev=1:1.2.11.dfsg-2+deb11u2 \
|
||||
libjpeg-dev=1:2.0.6-4 \
|
||||
libfreetype-dev=2.10.4+dfsg-1+deb11u1; \
|
||||
libcairo2=1.16.0-5; \
|
||||
fi; \
|
||||
rm -rf \
|
||||
/tmp/* \
|
||||
@@ -61,7 +60,7 @@ RUN \
|
||||
# Ubuntu python3-pip is missing wheel
|
||||
pip3 install --no-cache-dir \
|
||||
wheel==0.37.1 \
|
||||
platformio==6.1.10 \
|
||||
platformio==6.1.7 \
|
||||
# Change some platformio settings
|
||||
&& platformio settings set enable_telemetry No \
|
||||
&& platformio settings set check_platformio_interval 1000000 \
|
||||
|
||||
@@ -7,9 +7,7 @@ from esphome.core import CORE
|
||||
from esphome.components.esp32 import get_esp32_variant
|
||||
from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
@@ -72,22 +70,6 @@ ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
|
||||
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||
},
|
||||
VARIANT_ESP32C2: {
|
||||
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||
2: adc1_channel_t.ADC1_CHANNEL_2,
|
||||
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||
},
|
||||
VARIANT_ESP32C6: {
|
||||
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||
2: adc1_channel_t.ADC1_CHANNEL_2,
|
||||
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||
5: adc1_channel_t.ADC1_CHANNEL_5,
|
||||
6: adc1_channel_t.ADC1_CHANNEL_6,
|
||||
},
|
||||
VARIANT_ESP32H2: {
|
||||
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||
|
||||
@@ -9,7 +9,7 @@ CONF_ALLOW_MULTIPLE_TOUCHES = "allow_multiple_touches"
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["binary_sensor", "output"]
|
||||
CODEOWNERS = ["@mreditor97"]
|
||||
CODEOWNERS = ["@MrEditor97"]
|
||||
|
||||
cap1188_ns = cg.esphome_ns.namespace("cap1188")
|
||||
CONF_CAP1188_ID = "cap1188_id"
|
||||
|
||||
@@ -38,7 +38,7 @@ void CurrentBasedCover::control(const CoverCall &call) {
|
||||
}
|
||||
if (call.get_position().has_value()) {
|
||||
auto pos = *call.get_position();
|
||||
if (fabsf(this->position - pos) < 0.01) {
|
||||
if (pos == this->position) {
|
||||
// already at target
|
||||
} else {
|
||||
auto op = pos < this->position ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING;
|
||||
|
||||
@@ -12,15 +12,11 @@
|
||||
#include <esp_heap_caps.h>
|
||||
#include <esp_system.h>
|
||||
|
||||
#include <esp_chip_info.h>
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include <esp32/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||
#include <esp32c3/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
#include <esp32s2/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#include <esp32s3/rom/rtc.h>
|
||||
#include <esp_chip_info.h>
|
||||
#else
|
||||
#include <rom/rtc.h>
|
||||
#endif
|
||||
|
||||
#endif // USE_ESP32
|
||||
@@ -113,19 +109,13 @@ void DebugComponent::dump_config() {
|
||||
esp_chip_info_t info;
|
||||
esp_chip_info(&info);
|
||||
const char *model;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
model = "ESP32";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||
model = "ESP32-C3";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
model = "ESP32-S2";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
model = "ESP32-S3";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32H2)
|
||||
model = "ESP32-H2";
|
||||
#else
|
||||
model = "UNKNOWN";
|
||||
#endif
|
||||
switch (info.model) {
|
||||
case CHIP_ESP32:
|
||||
model = "ESP32";
|
||||
break;
|
||||
default:
|
||||
model = "UNKNOWN";
|
||||
}
|
||||
std::string features;
|
||||
if (info.features & CHIP_FEATURE_EMB_FLASH) {
|
||||
features += "EMB_FLASH,";
|
||||
@@ -167,26 +157,18 @@ void DebugComponent::dump_config() {
|
||||
case POWERON_RESET:
|
||||
reset_reason = "Power On Reset";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case SW_RESET:
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case RTC_SW_SYS_RESET:
|
||||
#endif
|
||||
reset_reason = "Software Reset Digital Core";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case OWDT_RESET:
|
||||
reset_reason = "Watch Dog Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
case DEEPSLEEP_RESET:
|
||||
reset_reason = "Deep Sleep Reset Digital Core";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case SDIO_RESET:
|
||||
reset_reason = "SLC Module Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
case TG0WDT_SYS_RESET:
|
||||
reset_reason = "Timer Group 0 Watch Dog Reset Digital Core";
|
||||
break;
|
||||
@@ -199,61 +181,24 @@ void DebugComponent::dump_config() {
|
||||
case INTRUSION_RESET:
|
||||
reset_reason = "Intrusion Reset CPU";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case TGWDT_CPU_RESET:
|
||||
reset_reason = "Timer Group Reset CPU";
|
||||
break;
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case TG0WDT_CPU_RESET:
|
||||
reset_reason = "Timer Group 0 Reset CPU";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case SW_CPU_RESET:
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case RTC_SW_CPU_RESET:
|
||||
#endif
|
||||
reset_reason = "Software Reset CPU";
|
||||
break;
|
||||
case RTCWDT_CPU_RESET:
|
||||
reset_reason = "RTC Watch Dog Reset CPU";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case EXT_CPU_RESET:
|
||||
reset_reason = "External CPU Reset";
|
||||
break;
|
||||
#endif
|
||||
case RTCWDT_BROWN_OUT_RESET:
|
||||
reset_reason = "Voltage Unstable Reset";
|
||||
break;
|
||||
case RTCWDT_RTC_RESET:
|
||||
reset_reason = "RTC Watch Dog Reset Digital Core And RTC Module";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case TG1WDT_CPU_RESET:
|
||||
reset_reason = "Timer Group 1 Reset CPU";
|
||||
break;
|
||||
case SUPER_WDT_RESET:
|
||||
reset_reason = "Super Watchdog Reset Digital Core And RTC Module";
|
||||
break;
|
||||
case GLITCH_RTC_RESET:
|
||||
reset_reason = "Glitch Reset Digital Core And RTC Module";
|
||||
break;
|
||||
case EFUSE_RESET:
|
||||
reset_reason = "eFuse Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case USB_UART_CHIP_RESET:
|
||||
reset_reason = "USB UART Reset Digital Core";
|
||||
break;
|
||||
case USB_JTAG_CHIP_RESET:
|
||||
reset_reason = "USB JTAG Reset Digital Core";
|
||||
break;
|
||||
case POWER_GLITCH_RESET:
|
||||
reset_reason = "Power Glitch Reset Digital Core And RTC Module";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
reset_reason = "Unknown Reset Reason";
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C6,
|
||||
)
|
||||
|
||||
WAKEUP_PINS = {
|
||||
@@ -96,8 +94,6 @@ WAKEUP_PINS = {
|
||||
20,
|
||||
21,
|
||||
],
|
||||
VARIANT_ESP32C2: [0, 1, 2, 3, 4, 5],
|
||||
VARIANT_ESP32C6: [0, 1, 2, 3, 4, 5, 6, 7],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ from .const import ( # noqa
|
||||
KEY_SDKCONFIG_OPTIONS,
|
||||
KEY_SUBMODULES,
|
||||
KEY_VARIANT,
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_FRIENDLY,
|
||||
VARIANTS,
|
||||
)
|
||||
|
||||
@@ -14,17 +14,13 @@ KEY_SUBMODULES = "submodules"
|
||||
VARIANT_ESP32 = "ESP32"
|
||||
VARIANT_ESP32S2 = "ESP32S2"
|
||||
VARIANT_ESP32S3 = "ESP32S3"
|
||||
VARIANT_ESP32C2 = "ESP32C2"
|
||||
VARIANT_ESP32C3 = "ESP32C3"
|
||||
VARIANT_ESP32C6 = "ESP32C6"
|
||||
VARIANT_ESP32H2 = "ESP32H2"
|
||||
VARIANTS = [
|
||||
VARIANT_ESP32,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
]
|
||||
|
||||
@@ -32,9 +28,7 @@ VARIANT_FRIENDLY = {
|
||||
VARIANT_ESP32: "ESP32",
|
||||
VARIANT_ESP32S2: "ESP32-S2",
|
||||
VARIANT_ESP32S3: "ESP32-S3",
|
||||
VARIANT_ESP32C2: "ESP32-C2",
|
||||
VARIANT_ESP32C3: "ESP32-C3",
|
||||
VARIANT_ESP32C6: "ESP32-C6",
|
||||
VARIANT_ESP32H2: "ESP32-H2",
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <esp_timer.h>
|
||||
#include <soc/rtc.h>
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include <hal/cpu_hal.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARDUINO
|
||||
#include <esp32-hal.h>
|
||||
@@ -53,7 +55,15 @@ void arch_init() {
|
||||
void IRAM_ATTR HOT arch_feed_wdt() { esp_task_wdt_reset(); }
|
||||
|
||||
uint8_t progmem_read_byte(const uint8_t *addr) { return *addr; }
|
||||
uint32_t arch_get_cpu_cycle_count() { return cpu_hal_get_cycle_count(); }
|
||||
uint32_t arch_get_cpu_cycle_count() {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
return cpu_hal_get_cycle_count();
|
||||
#else
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("esync; rsr %0,ccount" : "=a"(ccount));
|
||||
return ccount;
|
||||
#endif
|
||||
}
|
||||
uint32_t arch_get_cpu_freq_hz() { return rtc_clk_apb_freq_get(); }
|
||||
|
||||
#ifdef USE_ESP_IDF
|
||||
|
||||
@@ -26,8 +26,6 @@ from .const import (
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
esp32_ns,
|
||||
)
|
||||
@@ -37,8 +35,6 @@ from .gpio_esp32 import esp32_validate_gpio_pin, esp32_validate_supports
|
||||
from .gpio_esp32_s2 import esp32_s2_validate_gpio_pin, esp32_s2_validate_supports
|
||||
from .gpio_esp32_c3 import esp32_c3_validate_gpio_pin, esp32_c3_validate_supports
|
||||
from .gpio_esp32_s3 import esp32_s3_validate_gpio_pin, esp32_s3_validate_supports
|
||||
from .gpio_esp32_c2 import esp32_c2_validate_gpio_pin, esp32_c2_validate_supports
|
||||
from .gpio_esp32_c6 import esp32_c6_validate_gpio_pin, esp32_c6_validate_supports
|
||||
from .gpio_esp32_h2 import esp32_h2_validate_gpio_pin, esp32_h2_validate_supports
|
||||
|
||||
|
||||
@@ -99,14 +95,6 @@ _esp32_validations = {
|
||||
pin_validation=esp32_s3_validate_gpio_pin,
|
||||
usage_validation=esp32_s3_validate_supports,
|
||||
),
|
||||
VARIANT_ESP32C2: ESP32ValidationFunctions(
|
||||
pin_validation=esp32_c2_validate_gpio_pin,
|
||||
usage_validation=esp32_c2_validate_supports,
|
||||
),
|
||||
VARIANT_ESP32C6: ESP32ValidationFunctions(
|
||||
pin_validation=esp32_c6_validate_gpio_pin,
|
||||
usage_validation=esp32_c6_validate_supports,
|
||||
),
|
||||
VARIANT_ESP32H2: ESP32ValidationFunctions(
|
||||
pin_validation=esp32_h2_validate_gpio_pin,
|
||||
usage_validation=esp32_h2_validate_supports,
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import logging
|
||||
|
||||
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||
|
||||
import esphome.config_validation as cv
|
||||
|
||||
_ESP32C2_STRAPPING_PINS = {8, 9}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def esp32_c2_validate_gpio_pin(value):
|
||||
if value < 0 or value > 20:
|
||||
raise cv.Invalid(f"Invalid pin number: {value} (must be 0-20)")
|
||||
if value in _ESP32C2_STRAPPING_PINS:
|
||||
_LOGGER.warning(
|
||||
"GPIO%d is a Strapping PIN and should be avoided.\n"
|
||||
"Attaching external pullup/down resistors to strapping pins can cause unexpected failures.\n"
|
||||
"See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins",
|
||||
value,
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def esp32_c2_validate_supports(value):
|
||||
num = value[CONF_NUMBER]
|
||||
mode = value[CONF_MODE]
|
||||
is_input = mode[CONF_INPUT]
|
||||
|
||||
if num < 0 or num > 20:
|
||||
raise cv.Invalid(f"Invalid pin number: {value} (must be 0-20)")
|
||||
|
||||
if is_input:
|
||||
# All ESP32 pins support input mode
|
||||
pass
|
||||
return value
|
||||
@@ -1,50 +0,0 @@
|
||||
import logging
|
||||
|
||||
from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER
|
||||
|
||||
import esphome.config_validation as cv
|
||||
|
||||
_ESP32C6_SPI_PSRAM_PINS = {
|
||||
24: "SPICS0",
|
||||
25: "SPIQ",
|
||||
26: "SPIWP",
|
||||
27: "VDD_SPI",
|
||||
28: "SPIHD",
|
||||
29: "SPICLK",
|
||||
30: "SPID",
|
||||
}
|
||||
|
||||
_ESP32C6_STRAPPING_PINS = {8, 9, 15}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def esp32_c6_validate_gpio_pin(value):
|
||||
if value < 0 or value > 23:
|
||||
raise cv.Invalid(f"Invalid pin number: {value} (must be 0-23)")
|
||||
if value in _ESP32C6_SPI_PSRAM_PINS:
|
||||
raise cv.Invalid(
|
||||
f"This pin cannot be used on ESP32-C6s and is already used by the SPI/PSRAM interface (function: {_ESP32C6_SPI_PSRAM_PINS[value]})"
|
||||
)
|
||||
if value in _ESP32C6_STRAPPING_PINS:
|
||||
_LOGGER.warning(
|
||||
"GPIO%d is a Strapping PIN and should be avoided.\n"
|
||||
"Attaching external pullup/down resistors to strapping pins can cause unexpected failures.\n"
|
||||
"See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins",
|
||||
value,
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def esp32_c6_validate_supports(value):
|
||||
num = value[CONF_NUMBER]
|
||||
mode = value[CONF_MODE]
|
||||
is_input = mode[CONF_INPUT]
|
||||
|
||||
if num < 0 or num > 23:
|
||||
raise cv.Invalid(f"Invalid pin number: {value} (must be 0-23)")
|
||||
if is_input:
|
||||
# All ESP32 pins support input mode
|
||||
pass
|
||||
return value
|
||||
@@ -42,15 +42,9 @@ void BLEAdvertising::remove_service_uuid(ESPBTUUID uuid) {
|
||||
this->advertising_uuids_.end());
|
||||
}
|
||||
|
||||
void BLEAdvertising::set_manufacturer_data(const std::vector<uint8_t> &data) {
|
||||
delete[] this->advertising_data_.p_manufacturer_data;
|
||||
this->advertising_data_.p_manufacturer_data = nullptr;
|
||||
this->advertising_data_.manufacturer_len = data.size();
|
||||
if (!data.empty()) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
this->advertising_data_.p_manufacturer_data = new uint8_t[data.size()];
|
||||
memcpy(this->advertising_data_.p_manufacturer_data, data.data(), data.size());
|
||||
}
|
||||
void BLEAdvertising::set_manufacturer_data(uint8_t *data, uint16_t size) {
|
||||
this->advertising_data_.p_manufacturer_data = data;
|
||||
this->advertising_data_.manufacturer_len = size;
|
||||
}
|
||||
|
||||
void BLEAdvertising::start() {
|
||||
@@ -80,21 +74,16 @@ void BLEAdvertising::start() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->scan_response_) {
|
||||
memcpy(&this->scan_response_data_, &this->advertising_data_, sizeof(esp_ble_adv_data_t));
|
||||
this->scan_response_data_.set_scan_rsp = true;
|
||||
this->scan_response_data_.include_name = true;
|
||||
this->scan_response_data_.include_txpower = true;
|
||||
this->scan_response_data_.min_interval = 0;
|
||||
this->scan_response_data_.max_interval = 0;
|
||||
this->scan_response_data_.manufacturer_len = 0;
|
||||
this->scan_response_data_.appearance = 0;
|
||||
this->scan_response_data_.flag = 0;
|
||||
err = esp_ble_gap_config_adv_data(&this->scan_response_data_);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ble_gap_config_adv_data failed (Scan response): %d", err);
|
||||
return;
|
||||
}
|
||||
memcpy(&this->scan_response_data_, &this->advertising_data_, sizeof(esp_ble_adv_data_t));
|
||||
this->scan_response_data_.set_scan_rsp = true;
|
||||
this->scan_response_data_.include_name = true;
|
||||
this->scan_response_data_.include_txpower = true;
|
||||
this->scan_response_data_.appearance = 0;
|
||||
this->scan_response_data_.flag = 0;
|
||||
err = esp_ble_gap_config_adv_data(&this->scan_response_data_);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ble_gap_config_adv_data failed (Scan response): %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->advertising_data_.service_uuid_len > 0) {
|
||||
|
||||
@@ -20,7 +20,7 @@ class BLEAdvertising {
|
||||
void remove_service_uuid(ESPBTUUID uuid);
|
||||
void set_scan_response(bool scan_response) { this->scan_response_ = scan_response; }
|
||||
void set_min_preferred_interval(uint16_t interval) { this->advertising_data_.min_interval = interval; }
|
||||
void set_manufacturer_data(const std::vector<uint8_t> &data);
|
||||
void set_manufacturer_data(uint8_t *data, uint16_t size);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
@@ -6,12 +6,11 @@ from esphome.core import CORE
|
||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||
|
||||
AUTO_LOAD = ["esp32_ble"]
|
||||
CODEOWNERS = ["@jesserockz", "@clydebarrow"]
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
CONFLICTS_WITH = ["esp32_ble_beacon"]
|
||||
DEPENDENCIES = ["esp32"]
|
||||
|
||||
CONF_MANUFACTURER = "manufacturer"
|
||||
CONF_MANUFACTURER_DATA = "manufacturer_data"
|
||||
|
||||
esp32_ble_server_ns = cg.esphome_ns.namespace("esp32_ble_server")
|
||||
BLEServer = esp32_ble_server_ns.class_(
|
||||
@@ -28,7 +27,6 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
cv.GenerateID(): cv.declare_id(BLEServer),
|
||||
cv.GenerateID(esp32_ble.CONF_BLE_ID): cv.use_id(esp32_ble.ESP32BLE),
|
||||
cv.Optional(CONF_MANUFACTURER, default="ESPHome"): cv.string,
|
||||
cv.Optional(CONF_MANUFACTURER_DATA): cv.Schema([cv.hex_uint8_t]),
|
||||
cv.Optional(CONF_MODEL): cv.string,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
@@ -44,8 +42,6 @@ async def to_code(config):
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
cg.add(var.set_manufacturer(config[CONF_MANUFACTURER]))
|
||||
if CONF_MANUFACTURER_DATA in config:
|
||||
cg.add(var.set_manufacturer_data(config[CONF_MANUFACTURER_DATA]))
|
||||
if CONF_MODEL in config:
|
||||
cg.add(var.set_model(config[CONF_MODEL]))
|
||||
cg.add_define("USE_ESP32_BLE_SERVER")
|
||||
|
||||
@@ -68,7 +68,6 @@ void BLEServer::loop() {
|
||||
if (this->device_information_service_->is_running()) {
|
||||
this->state_ = RUNNING;
|
||||
this->can_proceed_ = true;
|
||||
this->restart_advertising_();
|
||||
ESP_LOGD(TAG, "BLE server setup successfully");
|
||||
} else if (!this->device_information_service_->is_starting()) {
|
||||
this->device_information_service_->start();
|
||||
@@ -78,13 +77,6 @@ void BLEServer::loop() {
|
||||
}
|
||||
}
|
||||
|
||||
void BLEServer::restart_advertising_() {
|
||||
if (this->state_ == RUNNING) {
|
||||
esp32_ble::global_ble->get_advertising()->set_manufacturer_data(this->manufacturer_data_);
|
||||
esp32_ble::global_ble->get_advertising()->start();
|
||||
}
|
||||
}
|
||||
|
||||
bool BLEServer::create_device_characteristics_() {
|
||||
if (this->model_.has_value()) {
|
||||
BLECharacteristic *model =
|
||||
|
||||
@@ -45,10 +45,6 @@ class BLEServer : public Component, public GATTsEventHandler, public Parented<ES
|
||||
|
||||
void set_manufacturer(const std::string &manufacturer) { this->manufacturer_ = manufacturer; }
|
||||
void set_model(const std::string &model) { this->model_ = model; }
|
||||
void set_manufacturer_data(const std::vector<uint8_t> &data) {
|
||||
this->manufacturer_data_ = data;
|
||||
this->restart_advertising_();
|
||||
}
|
||||
|
||||
std::shared_ptr<BLEService> create_service(const uint8_t *uuid, bool advertise = false);
|
||||
std::shared_ptr<BLEService> create_service(uint16_t uuid, bool advertise = false);
|
||||
@@ -67,7 +63,6 @@ class BLEServer : public Component, public GATTsEventHandler, public Parented<ES
|
||||
|
||||
protected:
|
||||
bool create_device_characteristics_();
|
||||
void restart_advertising_();
|
||||
|
||||
void add_client_(uint16_t conn_id, void *client) {
|
||||
this->clients_.insert(std::pair<uint16_t, void *>(conn_id, client));
|
||||
@@ -78,7 +73,6 @@ class BLEServer : public Component, public GATTsEventHandler, public Parented<ES
|
||||
|
||||
std::string manufacturer_;
|
||||
optional<std::string> model_;
|
||||
std::vector<uint8_t> manufacturer_data_;
|
||||
esp_gatt_if_t gatts_if_{0};
|
||||
bool registered_{false};
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ RMT_CHANNELS = {
|
||||
esp32.const.VARIANT_ESP32S2: [0, 1, 2, 3],
|
||||
esp32.const.VARIANT_ESP32S3: [0, 1, 2, 3],
|
||||
esp32.const.VARIANT_ESP32C3: [0, 1],
|
||||
esp32.const.VARIANT_ESP32C6: [0, 1],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
#include <driver/touch_sensor.h>
|
||||
#else
|
||||
#include <driver/touch_pad.h>
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32_touch {
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
|
||||
from esphome.components import esp32
|
||||
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
CONFLICTS_WITH = ["i2s_audio"]
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
DEPENDENCIES = ["esp32"]
|
||||
|
||||
CONF_ESP_ADF_ID = "esp_adf_id"
|
||||
|
||||
esp_adf_ns = cg.esphome_ns.namespace("esp_adf")
|
||||
ESPADF = esp_adf_ns.class_("ESPADF", cg.Component)
|
||||
ESPADFPipeline = esp_adf_ns.class_("ESPADFPipeline", cg.Parented.template(ESPADF))
|
||||
|
||||
SUPPORTED_BOARDS = {"esp32s3box": "CONFIG_ESP32_S3_BOX_BOARD"}
|
||||
|
||||
|
||||
def _validate_board(config):
|
||||
board = esp32.get_board()
|
||||
if board not in SUPPORTED_BOARDS:
|
||||
raise cv.Invalid(f"Board {board} is not supported by esp-adf")
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema({cv.GenerateID(): cv.declare_id(ESPADF)}),
|
||||
_validate_board,
|
||||
cv.only_with_esp_idf,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
cg.add_define("USE_ESP_ADF")
|
||||
|
||||
cg.add_platformio_option("build_unflags", "-Wl,--end-group")
|
||||
|
||||
esp32.add_idf_component(
|
||||
name="esp-adf",
|
||||
repo="https://github.com/espressif/esp-adf",
|
||||
path="components",
|
||||
ref="v2.5",
|
||||
components=["*"],
|
||||
submodules=["components/esp-sr", "components/esp-adf-libs"],
|
||||
)
|
||||
|
||||
esp32.add_idf_component(
|
||||
name="esp-dsp",
|
||||
repo="https://github.com/espressif/esp-dsp",
|
||||
ref="v1.2.0",
|
||||
)
|
||||
|
||||
cg.add_platformio_option(
|
||||
"board_build.embed_txtfiles", "components/dueros_service/duer_profile"
|
||||
)
|
||||
esp32.add_idf_sdkconfig_option(SUPPORTED_BOARDS[esp32.get_board()], True)
|
||||
@@ -1,26 +0,0 @@
|
||||
#include "esp_adf.h"
|
||||
|
||||
#ifdef USE_ESP_IDF
|
||||
|
||||
#include <board.h>
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace esp_adf {
|
||||
|
||||
static const char *const TAG = "esp_adf";
|
||||
|
||||
void ESPADF::setup() {
|
||||
ESP_LOGI(TAG, "Start codec chip");
|
||||
|
||||
audio_board_handle_t board_handle = audio_board_init();
|
||||
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
|
||||
}
|
||||
|
||||
float ESPADF::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
|
||||
} // namespace esp_adf
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP_IDF
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace esp_adf {
|
||||
class ESPADF;
|
||||
|
||||
class ESPADFPipeline : public Parented<ESPADF> {};
|
||||
|
||||
class ESPADF : public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
|
||||
float get_setup_priority() const override;
|
||||
|
||||
void lock() { this->lock_.lock(); }
|
||||
bool try_lock() { return this->lock_.try_lock(); }
|
||||
void unlock() { this->lock_.unlock(); }
|
||||
|
||||
protected:
|
||||
Mutex lock_;
|
||||
};
|
||||
|
||||
} // namespace esp_adf
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import microphone
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
from .. import CONF_ESP_ADF_ID, ESPADF, ESPADFPipeline, esp_adf_ns
|
||||
|
||||
AUTO_LOAD = ["esp_adf"]
|
||||
DEPENDENCIES = ["esp32"]
|
||||
|
||||
ESPADFMicrophone = esp_adf_ns.class_(
|
||||
"ESPADFMicrophone", ESPADFPipeline, microphone.Microphone, cg.Component
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
microphone.MICROPHONE_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESPADFMicrophone),
|
||||
cv.GenerateID(CONF_ESP_ADF_ID): cv.use_id(ESPADF),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
cv.only_with_esp_idf,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await cg.register_parented(var, config[CONF_ESP_ADF_ID])
|
||||
|
||||
await microphone.register_microphone(var, config)
|
||||
@@ -1,192 +0,0 @@
|
||||
#include "esp_adf_microphone.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <driver/i2s.h>
|
||||
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <audio_hal.h>
|
||||
#include <filter_resample.h>
|
||||
#include <i2s_stream.h>
|
||||
#include <raw_stream.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp_adf {
|
||||
|
||||
static const size_t BUFFER_SIZE = 1024;
|
||||
|
||||
static const char *const TAG = "esp_adf.microphone";
|
||||
|
||||
void ESPADFMicrophone::start() {
|
||||
if (this->is_failed())
|
||||
return;
|
||||
if (this->state_ == microphone::STATE_STOPPING) {
|
||||
ESP_LOGW(TAG, "Microphone is stopping, cannot start.");
|
||||
return;
|
||||
}
|
||||
this->state_ = microphone::STATE_STARTING;
|
||||
}
|
||||
void ESPADFMicrophone::start_() {
|
||||
if (!this->parent_->try_lock()) {
|
||||
return;
|
||||
}
|
||||
i2s_driver_config_t i2s_config = {
|
||||
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX),
|
||||
.sample_rate = 44100,
|
||||
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
|
||||
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
|
||||
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM,
|
||||
.dma_buf_count = 3,
|
||||
.dma_buf_len = 300,
|
||||
.use_apll = false,
|
||||
.tx_desc_auto_clear = true,
|
||||
.fixed_mclk = 0,
|
||||
.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
|
||||
.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "Init pipeline");
|
||||
audio_pipeline_cfg_t pipeline_cfg = {
|
||||
.rb_size = 8 * 1024,
|
||||
};
|
||||
this->pipeline_ = audio_pipeline_init(&pipeline_cfg);
|
||||
|
||||
ESP_LOGI(TAG, "Init i2s stream");
|
||||
i2s_stream_cfg_t i2s_cfg = {
|
||||
.type = AUDIO_STREAM_READER,
|
||||
.i2s_config = i2s_config,
|
||||
.i2s_port = I2S_NUM_0,
|
||||
.use_alc = false,
|
||||
.volume = 0,
|
||||
.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,
|
||||
.task_stack = I2S_STREAM_TASK_STACK,
|
||||
.task_core = I2S_STREAM_TASK_CORE,
|
||||
.task_prio = I2S_STREAM_TASK_PRIO,
|
||||
.stack_in_ext = false,
|
||||
.multi_out_num = 0,
|
||||
.uninstall_drv = true,
|
||||
.need_expand = false,
|
||||
.expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT,
|
||||
};
|
||||
this->i2s_stream_reader_ = i2s_stream_init(&i2s_cfg);
|
||||
|
||||
ESP_LOGI(TAG, "Init filter");
|
||||
rsp_filter_cfg_t rsp_cfg = {
|
||||
.src_rate = 44100,
|
||||
.src_ch = 2,
|
||||
.dest_rate = 16000,
|
||||
.dest_bits = 16,
|
||||
.dest_ch = 1,
|
||||
.src_bits = 16,
|
||||
.mode = RESAMPLE_DECODE_MODE,
|
||||
.max_indata_bytes = RSP_FILTER_BUFFER_BYTE,
|
||||
.out_len_bytes = RSP_FILTER_BUFFER_BYTE,
|
||||
.type = ESP_RESAMPLE_TYPE_AUTO,
|
||||
.complexity = 2,
|
||||
.down_ch_idx = 0,
|
||||
.prefer_flag = ESP_RSP_PREFER_TYPE_SPEED,
|
||||
.out_rb_size = RSP_FILTER_RINGBUFFER_SIZE,
|
||||
.task_stack = RSP_FILTER_TASK_STACK,
|
||||
.task_core = RSP_FILTER_TASK_CORE,
|
||||
.task_prio = RSP_FILTER_TASK_PRIO,
|
||||
.stack_in_ext = true,
|
||||
};
|
||||
this->filter_ = rsp_filter_init(&rsp_cfg);
|
||||
|
||||
ESP_LOGI(TAG, "Init raw stream");
|
||||
raw_stream_cfg_t raw_cfg = {
|
||||
.type = AUDIO_STREAM_READER,
|
||||
.out_rb_size = 8 * 1024,
|
||||
};
|
||||
this->raw_read_ = raw_stream_init(&raw_cfg);
|
||||
|
||||
ESP_LOGI(TAG, "Register all elements to audio pipeline");
|
||||
audio_pipeline_register(this->pipeline_, this->i2s_stream_reader_, "i2s");
|
||||
audio_pipeline_register(this->pipeline_, this->filter_, "filter");
|
||||
audio_pipeline_register(this->pipeline_, this->raw_read_, "raw");
|
||||
|
||||
const char *link_tag[3] = {"i2s", "filter", "raw"};
|
||||
audio_pipeline_link(this->pipeline_, &link_tag[0], 3);
|
||||
|
||||
ESP_LOGI(TAG, "Starting pipeline");
|
||||
audio_pipeline_run(this->pipeline_);
|
||||
|
||||
this->state_ = microphone::STATE_RUNNING;
|
||||
}
|
||||
|
||||
void ESPADFMicrophone::stop() {
|
||||
if (this->state_ == microphone::STATE_STOPPED || this->is_failed())
|
||||
return;
|
||||
if (this->state_ == microphone::STATE_STARTING) {
|
||||
this->state_ = microphone::STATE_STOPPED;
|
||||
return;
|
||||
}
|
||||
this->state_ = microphone::STATE_STOPPING;
|
||||
}
|
||||
|
||||
void ESPADFMicrophone::stop_() {
|
||||
ESP_LOGD(TAG, "Stopping microphone");
|
||||
audio_pipeline_stop(this->pipeline_);
|
||||
audio_pipeline_wait_for_stop(this->pipeline_);
|
||||
audio_pipeline_terminate(this->pipeline_);
|
||||
|
||||
audio_pipeline_unregister(this->pipeline_, this->i2s_stream_reader_);
|
||||
audio_pipeline_unregister(this->pipeline_, this->filter_);
|
||||
audio_pipeline_unregister(this->pipeline_, this->raw_read_);
|
||||
|
||||
audio_pipeline_deinit(this->pipeline_);
|
||||
audio_element_deinit(this->i2s_stream_reader_);
|
||||
audio_element_deinit(this->filter_);
|
||||
audio_element_deinit(this->raw_read_);
|
||||
|
||||
this->parent_->unlock();
|
||||
this->state_ = microphone::STATE_STOPPED;
|
||||
ESP_LOGD(TAG, "Microphone stopped");
|
||||
}
|
||||
|
||||
size_t ESPADFMicrophone::read(int16_t *buf, size_t len) {
|
||||
int bytes_read = raw_stream_read(this->raw_read_, (char *) buf, len);
|
||||
|
||||
if (bytes_read == ESP_FAIL) {
|
||||
ESP_LOGW(TAG, "Error reading from I2S microphone");
|
||||
this->status_set_warning();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
this->status_clear_warning();
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void ESPADFMicrophone::read_() {
|
||||
std::vector<int16_t> samples;
|
||||
samples.resize(BUFFER_SIZE);
|
||||
this->read(samples.data(), samples.size());
|
||||
|
||||
this->data_callbacks_.call(samples);
|
||||
}
|
||||
|
||||
void ESPADFMicrophone::loop() {
|
||||
switch (this->state_) {
|
||||
case microphone::STATE_STOPPED:
|
||||
break;
|
||||
case microphone::STATE_STARTING:
|
||||
this->start_();
|
||||
break;
|
||||
case microphone::STATE_RUNNING:
|
||||
if (this->data_callbacks_.size() > 0) {
|
||||
this->read_();
|
||||
}
|
||||
break;
|
||||
case microphone::STATE_STOPPING:
|
||||
this->stop_();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace esp_adf
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include "../esp_adf.h"
|
||||
|
||||
#include "esphome/components/microphone/microphone.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
#include <audio_element.h>
|
||||
#include <audio_pipeline.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp_adf {
|
||||
|
||||
class ESPADFMicrophone : public ESPADFPipeline, public microphone::Microphone, public Component {
|
||||
public:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
void loop() override;
|
||||
|
||||
size_t read(int16_t *buf, size_t len) override;
|
||||
|
||||
protected:
|
||||
void start_();
|
||||
void stop_();
|
||||
void read_();
|
||||
|
||||
audio_pipeline_handle_t pipeline_;
|
||||
audio_element_handle_t i2s_stream_reader_, filter_, raw_read_;
|
||||
};
|
||||
|
||||
} // namespace esp_adf
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
@@ -1,32 +0,0 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import speaker
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
from .. import CONF_ESP_ADF_ID, ESPADF, ESPADFPipeline, esp_adf_ns
|
||||
|
||||
AUTO_LOAD = ["esp_adf"]
|
||||
DEPENDENCIES = ["esp32"]
|
||||
|
||||
ESPADFSpeaker = esp_adf_ns.class_(
|
||||
"ESPADFSpeaker", ESPADFPipeline, speaker.Speaker, cg.Component
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESPADFSpeaker),
|
||||
cv.GenerateID(CONF_ESP_ADF_ID): cv.use_id(ESPADF),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
cv.only_with_esp_idf,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await cg.register_parented(var, config[CONF_ESP_ADF_ID])
|
||||
|
||||
await speaker.register_speaker(var, config)
|
||||
@@ -1,272 +0,0 @@
|
||||
#include "esp_adf_speaker.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <driver/i2s.h>
|
||||
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <audio_hal.h>
|
||||
#include <filter_resample.h>
|
||||
#include <i2s_stream.h>
|
||||
#include <raw_stream.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp_adf {
|
||||
|
||||
static const size_t BUFFER_COUNT = 50;
|
||||
|
||||
static const char *const TAG = "esp_adf.speaker";
|
||||
|
||||
void ESPADFSpeaker::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up ESP ADF Speaker...");
|
||||
|
||||
this->buffer_queue_ = xQueueCreate(BUFFER_COUNT, sizeof(DataEvent));
|
||||
this->event_queue_ = xQueueCreate(20, sizeof(TaskEvent));
|
||||
}
|
||||
|
||||
void ESPADFSpeaker::start() { this->state_ = speaker::STATE_STARTING; }
|
||||
void ESPADFSpeaker::start_() {
|
||||
if (!this->parent_->try_lock()) {
|
||||
return; // Waiting for another i2s component to return lock
|
||||
}
|
||||
this->state_ = speaker::STATE_RUNNING;
|
||||
|
||||
xTaskCreate(ESPADFSpeaker::player_task, "speaker_task", 8192, (void *) this, 0, &this->player_task_handle_);
|
||||
}
|
||||
|
||||
void ESPADFSpeaker::player_task(void *params) {
|
||||
ESPADFSpeaker *this_speaker = (ESPADFSpeaker *) params;
|
||||
|
||||
TaskEvent event;
|
||||
event.type = TaskEventType::STARTING;
|
||||
xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY);
|
||||
|
||||
i2s_driver_config_t i2s_config = {
|
||||
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX),
|
||||
.sample_rate = 16000,
|
||||
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
|
||||
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
|
||||
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM,
|
||||
.dma_buf_count = 8,
|
||||
.dma_buf_len = 1024,
|
||||
.use_apll = false,
|
||||
.tx_desc_auto_clear = true,
|
||||
.fixed_mclk = 0,
|
||||
.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
|
||||
.bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
|
||||
};
|
||||
|
||||
audio_pipeline_cfg_t pipeline_cfg = {
|
||||
.rb_size = 8 * 1024,
|
||||
};
|
||||
audio_pipeline_handle_t pipeline = audio_pipeline_init(&pipeline_cfg);
|
||||
|
||||
i2s_stream_cfg_t i2s_cfg = {
|
||||
.type = AUDIO_STREAM_WRITER,
|
||||
.i2s_config = i2s_config,
|
||||
.i2s_port = I2S_NUM_0,
|
||||
.use_alc = false,
|
||||
.volume = 0,
|
||||
.out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,
|
||||
.task_stack = I2S_STREAM_TASK_STACK,
|
||||
.task_core = I2S_STREAM_TASK_CORE,
|
||||
.task_prio = I2S_STREAM_TASK_PRIO,
|
||||
.stack_in_ext = false,
|
||||
.multi_out_num = 0,
|
||||
.uninstall_drv = true,
|
||||
.need_expand = false,
|
||||
.expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT,
|
||||
};
|
||||
audio_element_handle_t i2s_stream_writer = i2s_stream_init(&i2s_cfg);
|
||||
|
||||
rsp_filter_cfg_t rsp_cfg = {
|
||||
.src_rate = 16000,
|
||||
.src_ch = 1,
|
||||
.dest_rate = 16000,
|
||||
.dest_bits = 16,
|
||||
.dest_ch = 2,
|
||||
.src_bits = 16,
|
||||
.mode = RESAMPLE_DECODE_MODE,
|
||||
.max_indata_bytes = RSP_FILTER_BUFFER_BYTE,
|
||||
.out_len_bytes = RSP_FILTER_BUFFER_BYTE,
|
||||
.type = ESP_RESAMPLE_TYPE_AUTO,
|
||||
.complexity = 2,
|
||||
.down_ch_idx = 0,
|
||||
.prefer_flag = ESP_RSP_PREFER_TYPE_SPEED,
|
||||
.out_rb_size = RSP_FILTER_RINGBUFFER_SIZE,
|
||||
.task_stack = RSP_FILTER_TASK_STACK,
|
||||
.task_core = RSP_FILTER_TASK_CORE,
|
||||
.task_prio = RSP_FILTER_TASK_PRIO,
|
||||
.stack_in_ext = true,
|
||||
};
|
||||
audio_element_handle_t filter = rsp_filter_init(&rsp_cfg);
|
||||
|
||||
raw_stream_cfg_t raw_cfg = {
|
||||
.type = AUDIO_STREAM_WRITER,
|
||||
.out_rb_size = 8 * 1024,
|
||||
};
|
||||
audio_element_handle_t raw_write = raw_stream_init(&raw_cfg);
|
||||
|
||||
audio_pipeline_register(pipeline, raw_write, "raw");
|
||||
audio_pipeline_register(pipeline, filter, "filter");
|
||||
audio_pipeline_register(pipeline, i2s_stream_writer, "i2s");
|
||||
|
||||
const char *link_tag[3] = {
|
||||
"raw",
|
||||
// "filter",
|
||||
"i2s",
|
||||
};
|
||||
audio_pipeline_link(pipeline, &link_tag[0], 2);
|
||||
|
||||
audio_pipeline_run(pipeline);
|
||||
|
||||
DataEvent data_event;
|
||||
|
||||
event.type = TaskEventType::STARTED;
|
||||
xQueueSend(this_speaker->event_queue_, &event, 0);
|
||||
|
||||
uint32_t last_received = millis();
|
||||
|
||||
while (true) {
|
||||
if (xQueueReceive(this_speaker->buffer_queue_, &data_event, 0) != pdTRUE) {
|
||||
if (millis() - last_received > 100) {
|
||||
// No audio for 100ms, stop
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (data_event.stop) {
|
||||
// Stop signal from main thread
|
||||
while (xQueueReceive(this_speaker->buffer_queue_, &data_event, 0) == pdTRUE) {
|
||||
// Flush queue
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
size_t remaining = data_event.len;
|
||||
size_t current = 0;
|
||||
if (remaining > 0)
|
||||
last_received = millis();
|
||||
|
||||
while (remaining > 0) {
|
||||
int bytes_written = raw_stream_write(raw_write, (char *) data_event.data + current, remaining);
|
||||
if (bytes_written == ESP_FAIL) {
|
||||
event = {.type = TaskEventType::WARNING, .err = ESP_FAIL};
|
||||
xQueueSend(this_speaker->event_queue_, &event, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
remaining -= bytes_written;
|
||||
current += bytes_written;
|
||||
}
|
||||
|
||||
event.type = TaskEventType::PLAYING;
|
||||
xQueueSend(this_speaker->event_queue_, &event, 0);
|
||||
}
|
||||
|
||||
audio_pipeline_stop(pipeline);
|
||||
audio_pipeline_wait_for_stop(pipeline);
|
||||
audio_pipeline_terminate(pipeline);
|
||||
|
||||
event.type = TaskEventType::STOPPING;
|
||||
xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY);
|
||||
|
||||
audio_pipeline_unregister(pipeline, i2s_stream_writer);
|
||||
audio_pipeline_unregister(pipeline, filter);
|
||||
audio_pipeline_unregister(pipeline, raw_write);
|
||||
|
||||
audio_pipeline_deinit(pipeline);
|
||||
audio_element_deinit(i2s_stream_writer);
|
||||
audio_element_deinit(filter);
|
||||
audio_element_deinit(raw_write);
|
||||
|
||||
event.type = TaskEventType::STOPPED;
|
||||
xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY);
|
||||
|
||||
while (true) {
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPADFSpeaker::stop() {
|
||||
if (this->state_ == speaker::STATE_STOPPED)
|
||||
return;
|
||||
if (this->state_ == speaker::STATE_STARTING) {
|
||||
this->state_ = speaker::STATE_STOPPED;
|
||||
return;
|
||||
}
|
||||
this->state_ = speaker::STATE_STOPPING;
|
||||
DataEvent data;
|
||||
data.stop = true;
|
||||
xQueueSendToFront(this->buffer_queue_, &data, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void ESPADFSpeaker::watch_() {
|
||||
TaskEvent event;
|
||||
if (xQueueReceive(this->event_queue_, &event, 0) == pdTRUE) {
|
||||
switch (event.type) {
|
||||
case TaskEventType::STARTING:
|
||||
case TaskEventType::STARTED:
|
||||
case TaskEventType::STOPPING:
|
||||
break;
|
||||
case TaskEventType::PLAYING:
|
||||
this->status_clear_warning();
|
||||
break;
|
||||
case TaskEventType::STOPPED:
|
||||
this->parent_->unlock();
|
||||
this->state_ = speaker::STATE_STOPPED;
|
||||
vTaskDelete(this->player_task_handle_);
|
||||
this->player_task_handle_ = nullptr;
|
||||
break;
|
||||
case TaskEventType::WARNING:
|
||||
ESP_LOGW(TAG, "Error writing to pipeline: %s", esp_err_to_name(event.err));
|
||||
this->status_set_warning();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESPADFSpeaker::loop() {
|
||||
switch (this->state_) {
|
||||
case speaker::STATE_STARTING:
|
||||
this->start_();
|
||||
break;
|
||||
case speaker::STATE_RUNNING:
|
||||
this->watch_();
|
||||
break;
|
||||
case speaker::STATE_STOPPING:
|
||||
case speaker::STATE_STOPPED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t ESPADFSpeaker::play(const uint8_t *data, size_t length) {
|
||||
if (this->state_ != speaker::STATE_RUNNING && this->state_ != speaker::STATE_STARTING) {
|
||||
this->start();
|
||||
}
|
||||
size_t remaining = length;
|
||||
size_t index = 0;
|
||||
while (remaining > 0) {
|
||||
DataEvent event;
|
||||
event.stop = false;
|
||||
size_t to_send_length = std::min(remaining, BUFFER_SIZE);
|
||||
event.len = to_send_length;
|
||||
memcpy(event.data, data + index, to_send_length);
|
||||
if (xQueueSend(this->buffer_queue_, &event, 0) != pdTRUE) {
|
||||
return index; // Queue full
|
||||
}
|
||||
remaining -= to_send_length;
|
||||
index += to_send_length;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
} // namespace esp_adf
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
@@ -1,68 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include "../esp_adf.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
#include "esphome/components/speaker/speaker.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include <audio_element.h>
|
||||
#include <audio_pipeline.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace esp_adf {
|
||||
|
||||
static const size_t BUFFER_SIZE = 1024;
|
||||
|
||||
enum class TaskEventType : uint8_t {
|
||||
STARTING = 0,
|
||||
STARTED,
|
||||
PLAYING,
|
||||
STOPPING,
|
||||
STOPPED,
|
||||
WARNING = 255,
|
||||
};
|
||||
|
||||
struct TaskEvent {
|
||||
TaskEventType type;
|
||||
esp_err_t err;
|
||||
};
|
||||
|
||||
struct DataEvent {
|
||||
bool stop;
|
||||
size_t len;
|
||||
uint8_t data[BUFFER_SIZE];
|
||||
};
|
||||
|
||||
class ESPADFSpeaker : public ESPADFPipeline, public speaker::Speaker, public Component {
|
||||
public:
|
||||
float get_setup_priority() const override { return esphome::setup_priority::LATE; }
|
||||
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
size_t play(const uint8_t *data, size_t length) override;
|
||||
|
||||
protected:
|
||||
void start_();
|
||||
void watch_();
|
||||
|
||||
static void player_task(void *params);
|
||||
|
||||
TaskHandle_t player_task_handle_{nullptr};
|
||||
QueueHandle_t buffer_queue_;
|
||||
QueueHandle_t event_queue_;
|
||||
};
|
||||
|
||||
} // namespace esp_adf
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ESP32
|
||||
@@ -89,7 +89,7 @@ SUPPORTED_SWING_MODES_OPTIONS = {
|
||||
|
||||
SUPPORTED_CLIMATE_MODES_OPTIONS = {
|
||||
"OFF": ClimateMode.CLIMATE_MODE_OFF, # always available
|
||||
"HEAT_COOL": ClimateMode.CLIMATE_MODE_HEAT_COOL, # always available
|
||||
"AUTO": ClimateMode.CLIMATE_MODE_AUTO, # always available
|
||||
"COOL": ClimateMode.CLIMATE_MODE_COOL,
|
||||
"HEAT": ClimateMode.CLIMATE_MODE_HEAT,
|
||||
"DRY": ClimateMode.CLIMATE_MODE_DRY,
|
||||
|
||||
@@ -72,7 +72,7 @@ HaierClimateBase::HaierClimateBase()
|
||||
this->traits_ = climate::ClimateTraits();
|
||||
this->traits_.set_supported_modes({climate::CLIMATE_MODE_OFF, climate::CLIMATE_MODE_COOL, climate::CLIMATE_MODE_HEAT,
|
||||
climate::CLIMATE_MODE_FAN_ONLY, climate::CLIMATE_MODE_DRY,
|
||||
climate::CLIMATE_MODE_HEAT_COOL});
|
||||
climate::CLIMATE_MODE_AUTO});
|
||||
this->traits_.set_supported_fan_modes(
|
||||
{climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, climate::CLIMATE_FAN_HIGH});
|
||||
this->traits_.set_supported_swing_modes({climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_BOTH,
|
||||
@@ -171,8 +171,8 @@ void HaierClimateBase::set_answer_timeout(uint32_t timeout) {
|
||||
|
||||
void HaierClimateBase::set_supported_modes(const std::set<climate::ClimateMode> &modes) {
|
||||
this->traits_.set_supported_modes(modes);
|
||||
this->traits_.add_supported_mode(climate::CLIMATE_MODE_OFF); // Always available
|
||||
this->traits_.add_supported_mode(climate::CLIMATE_MODE_HEAT_COOL); // Always available
|
||||
this->traits_.add_supported_mode(climate::CLIMATE_MODE_OFF); // Always available
|
||||
this->traits_.add_supported_mode(climate::CLIMATE_MODE_AUTO); // Always available
|
||||
}
|
||||
|
||||
void HaierClimateBase::set_supported_presets(const std::set<climate::ClimatePreset> &presets) {
|
||||
|
||||
@@ -458,7 +458,7 @@ haier_protocol::HaierMessage HonClimate::get_control_message() {
|
||||
case CLIMATE_MODE_OFF:
|
||||
out_data->ac_power = 0;
|
||||
break;
|
||||
case CLIMATE_MODE_HEAT_COOL:
|
||||
case CLIMATE_MODE_AUTO:
|
||||
out_data->ac_power = 1;
|
||||
out_data->ac_mode = (uint8_t) hon_protocol::ConditioningMode::AUTO;
|
||||
out_data->fan_mode = this->other_modes_fan_speed_;
|
||||
@@ -758,7 +758,7 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
|
||||
this->mode = CLIMATE_MODE_FAN_ONLY;
|
||||
break;
|
||||
case (uint8_t) hon_protocol::ConditioningMode::AUTO:
|
||||
this->mode = CLIMATE_MODE_HEAT_COOL;
|
||||
this->mode = CLIMATE_MODE_AUTO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ haier_protocol::HaierMessage Smartair2Climate::get_control_message() {
|
||||
out_data->ac_power = 0;
|
||||
break;
|
||||
|
||||
case CLIMATE_MODE_HEAT_COOL:
|
||||
case CLIMATE_MODE_AUTO:
|
||||
out_data->ac_power = 1;
|
||||
out_data->ac_mode = (uint8_t) smartair2_protocol::ConditioningMode::AUTO;
|
||||
out_data->fan_mode = this->other_modes_fan_speed_;
|
||||
@@ -487,7 +487,7 @@ haier_protocol::HandlerError Smartair2Climate::process_status_message_(const uin
|
||||
this->mode = CLIMATE_MODE_FAN_ONLY;
|
||||
break;
|
||||
case (uint8_t) smartair2_protocol::ConditioningMode::AUTO:
|
||||
this->mode = CLIMATE_MODE_HEAT_COOL;
|
||||
this->mode = CLIMATE_MODE_AUTO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ PROTOCOLS = {
|
||||
"greeya": Protocol.PROTOCOL_GREEYAA,
|
||||
"greeyan": Protocol.PROTOCOL_GREEYAN,
|
||||
"greeyac": Protocol.PROTOCOL_GREEYAC,
|
||||
"greeyt": Protocol.PROTOCOL_GREEYT,
|
||||
"hisense_aud": Protocol.PROTOCOL_HISENSE_AUD,
|
||||
"hitachi": Protocol.PROTOCOL_HITACHI,
|
||||
"hyundai": Protocol.PROTOCOL_HYUNDAI,
|
||||
@@ -116,7 +115,7 @@ def to_code(config):
|
||||
cg.add(var.set_max_temperature(config[CONF_MAX_TEMPERATURE]))
|
||||
cg.add(var.set_min_temperature(config[CONF_MIN_TEMPERATURE]))
|
||||
|
||||
cg.add_library("tonia/HeatpumpIR", "1.0.23")
|
||||
cg.add_library("tonia/HeatpumpIR", "1.0.20")
|
||||
|
||||
if CORE.is_esp8266 or CORE.is_esp32:
|
||||
cg.add_library("crankyoldgit/IRremoteESP8266", "2.7.12")
|
||||
|
||||
@@ -27,7 +27,6 @@ const std::map<Protocol, std::function<HeatpumpIR *()>> PROTOCOL_CONSTRUCTOR_MAP
|
||||
{PROTOCOL_GREEYAA, []() { return new GreeYAAHeatpumpIR(); }}, // NOLINT
|
||||
{PROTOCOL_GREEYAN, []() { return new GreeYANHeatpumpIR(); }}, // NOLINT
|
||||
{PROTOCOL_GREEYAC, []() { return new GreeYACHeatpumpIR(); }}, // NOLINT
|
||||
{PROTOCOL_GREEYT, []() { return new GreeYTHeatpumpIR(); }}, // NOLINT
|
||||
{PROTOCOL_HISENSE_AUD, []() { return new HisenseHeatpumpIR(); }}, // NOLINT
|
||||
{PROTOCOL_HITACHI, []() { return new HitachiHeatpumpIR(); }}, // NOLINT
|
||||
{PROTOCOL_HYUNDAI, []() { return new HyundaiHeatpumpIR(); }}, // NOLINT
|
||||
|
||||
@@ -27,7 +27,6 @@ enum Protocol {
|
||||
PROTOCOL_GREEYAA,
|
||||
PROTOCOL_GREEYAN,
|
||||
PROTOCOL_GREEYAC,
|
||||
PROTOCOL_GREEYT,
|
||||
PROTOCOL_HISENSE_AUD,
|
||||
PROTOCOL_HITACHI,
|
||||
PROTOCOL_HYUNDAI,
|
||||
|
||||
@@ -23,13 +23,13 @@ CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HTU21DComponent),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
cv.Required(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_HUMIDITY,
|
||||
|
||||
@@ -16,7 +16,7 @@ from esphome.const import (
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
CODEOWNERS = ["@mreditor97"]
|
||||
CODEOWNERS = ["@MrEditor97"]
|
||||
|
||||
ina260_ns = cg.esphome_ns.namespace("ina260")
|
||||
INA260Component = ina260_ns.class_(
|
||||
|
||||
@@ -28,8 +28,6 @@ from esphome.components.esp32.const import (
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32S3,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C6,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
@@ -76,8 +74,6 @@ UART_SELECTION_ESP32 = {
|
||||
VARIANT_ESP32S2: [UART0, UART1, USB_CDC],
|
||||
VARIANT_ESP32S3: [UART0, UART1, USB_CDC, USB_SERIAL_JTAG],
|
||||
VARIANT_ESP32C3: [UART0, UART1, USB_SERIAL_JTAG],
|
||||
VARIANT_ESP32C2: [UART0, UART1],
|
||||
VARIANT_ESP32C6: [UART0, UART1, USB_CDC, USB_SERIAL_JTAG],
|
||||
}
|
||||
|
||||
UART_SELECTION_ESP8266 = [UART0, UART0_SWAP, UART1]
|
||||
|
||||
@@ -120,7 +120,7 @@ void HOT Logger::log_message_(int level, const char *tag, int offset) {
|
||||
if (
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
uart_ == UART_SELECTION_USB_CDC
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||
uart_ == UART_SELECTION_USB_SERIAL_JTAG
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
uart_ == UART_SELECTION_USB_CDC || uart_ == UART_SELECTION_USB_SERIAL_JTAG
|
||||
@@ -191,8 +191,8 @@ void Logger::pre_setup() {
|
||||
Serial1.setDebugOutput(ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE);
|
||||
#endif
|
||||
break;
|
||||
#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) && \
|
||||
!defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) && \
|
||||
!defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case UART_SELECTION_UART2:
|
||||
this->hw_serial_ = &Serial2;
|
||||
Serial2.begin(this->baud_rate_);
|
||||
@@ -215,8 +215,7 @@ void Logger::pre_setup() {
|
||||
case UART_SELECTION_UART1:
|
||||
uart_num_ = UART_NUM_1;
|
||||
break;
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) && \
|
||||
!defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case UART_SELECTION_UART2:
|
||||
uart_num_ = UART_NUM_2;
|
||||
break;
|
||||
@@ -226,11 +225,11 @@ void Logger::pre_setup() {
|
||||
uart_num_ = -1;
|
||||
break;
|
||||
#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case UART_SELECTION_USB_SERIAL_JTAG:
|
||||
uart_num_ = -1;
|
||||
break;
|
||||
#endif // USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32S3
|
||||
#endif // USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32S3
|
||||
}
|
||||
if (uart_num_ >= 0) {
|
||||
uart_config_t uart_config{};
|
||||
@@ -279,8 +278,7 @@ const char *const LOG_LEVELS[] = {"NONE", "ERROR", "WARN", "INFO", "CONFIG", "DE
|
||||
#ifdef USE_ESP32
|
||||
const char *const UART_SELECTIONS[] = {
|
||||
"UART0", "UART1",
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) && \
|
||||
!defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
"UART2",
|
||||
#endif // !USE_ESP32_VARIANT_ESP32C3 && !USE_ESP32_VARIANT_ESP32S2 && !USE_ESP32_VARIANT_ESP32S3
|
||||
#if defined(USE_ESP_IDF)
|
||||
|
||||
@@ -34,15 +34,14 @@ enum UARTSelection {
|
||||
UART_SELECTION_UART0 = 0,
|
||||
UART_SELECTION_UART1,
|
||||
#if defined(USE_ESP32)
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) && \
|
||||
!defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
UART_SELECTION_UART2,
|
||||
#endif // !USE_ESP32_VARIANT_ESP32C3 && !USE_ESP32_VARIANT_ESP32S2 && !USE_ESP32_VARIANT_ESP32S3
|
||||
#ifdef USE_ESP_IDF
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
UART_SELECTION_USB_CDC,
|
||||
#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
UART_SELECTION_USB_SERIAL_JTAG,
|
||||
#endif // USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32S3
|
||||
#endif // USE_ESP_IDF
|
||||
|
||||
@@ -13,7 +13,7 @@ CONF_HOT_JUNCTION = "hot_junction"
|
||||
CONF_COLD_JUNCTION = "cold_junction"
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
CODEOWNERS = ["@mreditor97"]
|
||||
CODEOWNERS = ["@MrEditor97"]
|
||||
|
||||
mcp9600_ns = cg.esphome_ns.namespace("mcp9600")
|
||||
MCP9600Component = mcp9600_ns.class_(
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
CODEOWNERS = ["@SeByDocKy"]
|
||||
@@ -1,115 +0,0 @@
|
||||
#include "pmwcs3.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace pmwcs3 {
|
||||
|
||||
static const uint8_t PMWCS3_I2C_ADDRESS = 0x63;
|
||||
static const uint8_t PMWCS3_REG_READ_START = 0x01;
|
||||
static const uint8_t PMWCS3_REG_READ_E25 = 0x02;
|
||||
static const uint8_t PMWCS3_REG_READ_EC = 0x03;
|
||||
static const uint8_t PMWCS3_REG_READ_TEMP = 0x04;
|
||||
static const uint8_t PMWCS3_REG_READ_VWC = 0x05;
|
||||
static const uint8_t PMWCS3_REG_CALIBRATE_AIR = 0x06;
|
||||
static const uint8_t PMWCS3_REG_CALIBRATE_WATER = 0x07;
|
||||
static const uint8_t PMWCS3_SET_I2C_ADDRESS = 0x08;
|
||||
static const uint8_t PMWCS3_REG_GET_DATA = 0x09;
|
||||
static const uint8_t PMWCS3_REG_CALIBRATE_EC = 0x10;
|
||||
static const uint8_t PMWCS3_REG_CAP = 0x0A;
|
||||
static const uint8_t PMWCS3_REG_RES = 0x0B;
|
||||
static const uint8_t PMWCS3_REG_RC = 0x0C;
|
||||
static const uint8_t PMWCS3_REG_RT = 0x0D;
|
||||
|
||||
static const char *const TAG = "pmwcs3";
|
||||
|
||||
void PMWCS3Component::new_i2c_address(uint8_t address) {
|
||||
if (!this->write_byte(PMWCS3_SET_I2C_ADDRESS, address)) {
|
||||
this->status_set_warning();
|
||||
ESP_LOGW(TAG, "couldn't write the new I2C address %d", address);
|
||||
return;
|
||||
}
|
||||
this->set_i2c_address(address); // Allows device to continue working until new firmware is written with new address.
|
||||
ESP_LOGVV(TAG, "changed I2C address to %d", address);
|
||||
this->status_clear_warning();
|
||||
}
|
||||
|
||||
void PMWCS3Component::air_calibration() {
|
||||
if (!this->write_bytes(PMWCS3_REG_CALIBRATE_AIR, nullptr, 0)) {
|
||||
this->status_set_warning();
|
||||
ESP_LOGW(TAG, "couldn't start air calibration");
|
||||
return;
|
||||
}
|
||||
ESP_LOGW(TAG, "Start air calibration during the next 300s");
|
||||
}
|
||||
void PMWCS3Component::water_calibration() {
|
||||
if (!this->write_bytes(PMWCS3_REG_CALIBRATE_WATER, nullptr, 0)) {
|
||||
this->status_set_warning();
|
||||
ESP_LOGW(TAG, "couldn't start water calibration");
|
||||
return;
|
||||
}
|
||||
ESP_LOGW(TAG, "Start water calibration during the next 300s");
|
||||
}
|
||||
|
||||
void PMWCS3Component::setup() { ESP_LOGCONFIG(TAG, "Setting up PMWCS3..."); }
|
||||
|
||||
void PMWCS3Component::update() { this->read_data_(); }
|
||||
|
||||
float PMWCS3Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
void PMWCS3Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "PMWCS3");
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "Communication with PMWCS3 failed!");
|
||||
}
|
||||
ESP_LOGI(TAG, "%s", this->is_failed() ? "FAILED" : "OK");
|
||||
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
LOG_SENSOR(" ", "e25", this->e25_sensor_);
|
||||
LOG_SENSOR(" ", "ec", this->ec_sensor_);
|
||||
LOG_SENSOR(" ", "temperature", this->temperature_sensor_);
|
||||
LOG_SENSOR(" ", "vwc", this->vwc_sensor_);
|
||||
}
|
||||
void PMWCS3Component::read_data_() {
|
||||
uint8_t data[8];
|
||||
float e25, ec, temperature, vwc;
|
||||
|
||||
/////// Super important !!!! first activate reading PMWCS3_REG_READ_START (if not, return always the same values) ////
|
||||
|
||||
if (!this->write_bytes(PMWCS3_REG_READ_START, nullptr, 0)) {
|
||||
this->status_set_warning();
|
||||
ESP_LOGVV(TAG, "Failed to write into REG_READ_START register !!!");
|
||||
return;
|
||||
}
|
||||
// NOLINT delay(100);
|
||||
|
||||
if (!this->read_bytes(PMWCS3_REG_GET_DATA, (uint8_t *) &data, 8)) {
|
||||
ESP_LOGVV(TAG, "Error reading PMWCS3_REG_GET_DATA registers");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
if (this->e25_sensor_ != nullptr) {
|
||||
e25 = ((data[1] << 8) | data[0]) / 100.0;
|
||||
this->e25_sensor_->publish_state(e25);
|
||||
ESP_LOGVV(TAG, "e25: data[0]=%d, data[1]=%d, result=%f", data[0], data[1], e25);
|
||||
}
|
||||
if (this->ec_sensor_ != nullptr) {
|
||||
ec = ((data[3] << 8) | data[2]) / 10.0;
|
||||
this->ec_sensor_->publish_state(ec);
|
||||
ESP_LOGVV(TAG, "ec: data[2]=%d, data[3]=%d, result=%f", data[2], data[3], ec);
|
||||
}
|
||||
if (this->temperature_sensor_ != nullptr) {
|
||||
temperature = ((data[5] << 8) | data[4]) / 100.0;
|
||||
this->temperature_sensor_->publish_state(temperature);
|
||||
ESP_LOGVV(TAG, "temp: data[4]=%d, data[5]=%d, result=%f", data[4], data[5], temperature);
|
||||
}
|
||||
if (this->vwc_sensor_ != nullptr) {
|
||||
vwc = ((data[7] << 8) | data[6]) / 10.0;
|
||||
this->vwc_sensor_->publish_state(vwc);
|
||||
ESP_LOGVV(TAG, "vwc: data[6]=%d, data[7]=%d, result=%f", data[6], data[7], vwc);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pmwcs3
|
||||
} // namespace esphome
|
||||
@@ -1,70 +0,0 @@
|
||||
#pragma once
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
// ref:
|
||||
// https://github.com/tinovi/i2cArduino/blob/master/i2cArduino.h
|
||||
|
||||
namespace esphome {
|
||||
namespace pmwcs3 {
|
||||
|
||||
class PMWCS3Component : public PollingComponent, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
float get_setup_priority() const override;
|
||||
|
||||
void set_e25_sensor(sensor::Sensor *e25_sensor) { e25_sensor_ = e25_sensor; }
|
||||
void set_ec_sensor(sensor::Sensor *ec_sensor) { ec_sensor_ = ec_sensor; }
|
||||
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; }
|
||||
void set_vwc_sensor(sensor::Sensor *vwc_sensor) { vwc_sensor_ = vwc_sensor; }
|
||||
|
||||
void new_i2c_address(uint8_t newaddress);
|
||||
void air_calibration();
|
||||
void water_calibration();
|
||||
|
||||
protected:
|
||||
void read_data_();
|
||||
|
||||
sensor::Sensor *e25_sensor_{nullptr};
|
||||
sensor::Sensor *ec_sensor_{nullptr};
|
||||
sensor::Sensor *temperature_sensor_{nullptr};
|
||||
sensor::Sensor *vwc_sensor_{nullptr};
|
||||
};
|
||||
|
||||
template<typename... Ts> class PMWCS3AirCalibrationAction : public Action<Ts...> {
|
||||
public:
|
||||
PMWCS3AirCalibrationAction(PMWCS3Component *parent) : parent_(parent) {}
|
||||
|
||||
void play(Ts... x) override { this->parent_->air_calibration(); }
|
||||
|
||||
protected:
|
||||
PMWCS3Component *parent_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class PMWCS3WaterCalibrationAction : public Action<Ts...> {
|
||||
public:
|
||||
PMWCS3WaterCalibrationAction(PMWCS3Component *parent) : parent_(parent) {}
|
||||
|
||||
void play(Ts... x) override { this->parent_->water_calibration(); }
|
||||
|
||||
protected:
|
||||
PMWCS3Component *parent_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class PMWCS3NewI2cAddressAction : public Action<Ts...> {
|
||||
public:
|
||||
PMWCS3NewI2cAddressAction(PMWCS3Component *parent) : parent_(parent) {}
|
||||
TEMPLATABLE_VALUE(int, new_address)
|
||||
|
||||
void play(Ts... x) override { this->parent_->new_i2c_address(this->new_address_.value(x...)); }
|
||||
|
||||
protected:
|
||||
PMWCS3Component *parent_;
|
||||
};
|
||||
|
||||
} // namespace pmwcs3
|
||||
} // namespace esphome
|
||||
@@ -1,140 +0,0 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome import automation
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_ADDRESS,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_EC,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
ICON_THERMOMETER,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@SeByDocKy"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
CONF_E25 = "e25"
|
||||
CONF_VWC = "vwc"
|
||||
|
||||
ICON_EPSILON = "mdi:epsilon"
|
||||
ICON_SIGMA = "mdi:sigma-lower"
|
||||
ICON_ALPHA = "mdi:alpha-h-circle-outline"
|
||||
|
||||
pmwcs3_ns = cg.esphome_ns.namespace("pmwcs3")
|
||||
PMWCS3Component = pmwcs3_ns.class_(
|
||||
"PMWCS3Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
# Actions
|
||||
PMWCS3AirCalibrationAction = pmwcs3_ns.class_(
|
||||
"PMWCS3AirCalibrationAction", automation.Action
|
||||
)
|
||||
PMWCS3WaterCalibrationAction = pmwcs3_ns.class_(
|
||||
"PMWCS3WaterCalibrationAction", automation.Action
|
||||
)
|
||||
PMWCS3NewI2cAddressAction = pmwcs3_ns.class_(
|
||||
"PMWCS3NewI2cAddressAction", automation.Action
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PMWCS3Component),
|
||||
cv.Optional(CONF_E25): sensor.sensor_schema(
|
||||
icon=ICON_EPSILON,
|
||||
accuracy_decimals=3,
|
||||
unit_of_measurement="dS/m",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_EC): sensor.sensor_schema(
|
||||
icon=ICON_SIGMA,
|
||||
accuracy_decimals=2,
|
||||
unit_of_measurement="mS/m",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
icon=ICON_THERMOMETER,
|
||||
accuracy_decimals=3,
|
||||
unit_of_measurement="°C",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_VWC): sensor.sensor_schema(
|
||||
icon=ICON_ALPHA,
|
||||
accuracy_decimals=3,
|
||||
unit_of_measurement="cm3cm−3",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x63))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_E25 in config:
|
||||
sens = await sensor.new_sensor(config[CONF_E25])
|
||||
cg.add(var.set_e25_sensor(sens))
|
||||
|
||||
if CONF_EC in config:
|
||||
sens = await sensor.new_sensor(config[CONF_EC])
|
||||
cg.add(var.set_ec_sensor(sens))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
|
||||
if CONF_VWC in config:
|
||||
sens = await sensor.new_sensor(config[CONF_VWC])
|
||||
cg.add(var.set_vwc_sensor(sens))
|
||||
|
||||
|
||||
# Actions
|
||||
PMWCS3_CALIBRATION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(PMWCS3Component),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"pmwcs3.air_calibration",
|
||||
PMWCS3AirCalibrationAction,
|
||||
PMWCS3_CALIBRATION_SCHEMA,
|
||||
)
|
||||
@automation.register_action(
|
||||
"pmwcs3.water_calibration",
|
||||
PMWCS3WaterCalibrationAction,
|
||||
PMWCS3_CALIBRATION_SCHEMA,
|
||||
)
|
||||
async def pmwcs3_calibration_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
return var
|
||||
|
||||
|
||||
PMWCS3_NEW_I2C_ADDRESS_SCHEMA = cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(PMWCS3Component),
|
||||
cv.Required(CONF_ADDRESS): cv.templatable(cv.i2c_address),
|
||||
},
|
||||
key=CONF_ADDRESS,
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"pmwcs3.new_i2c_address",
|
||||
PMWCS3NewI2cAddressAction,
|
||||
PMWCS3_NEW_I2C_ADDRESS_SCHEMA,
|
||||
)
|
||||
async def pmwcs3newi2caddress_to_code(config, action_id, template_arg, args):
|
||||
parent = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, parent)
|
||||
address = await cg.templatable(config[CONF_ADDRESS], args, int)
|
||||
cg.add(var.set_new_address(address))
|
||||
return var
|
||||
@@ -96,7 +96,7 @@ std::string AEHAProtocol::format_data_(const std::vector<uint8_t> &data) {
|
||||
|
||||
void AEHAProtocol::dump(const AEHAData &data) {
|
||||
auto data_str = format_data_(data.data);
|
||||
ESP_LOGI(TAG, "Received AEHA: address=0x%04X, data=[%s]", data.address, data_str.c_str());
|
||||
ESP_LOGD(TAG, "Received AEHA: address=0x%04X, data=[%s]", data.address, data_str.c_str());
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -96,10 +96,10 @@ optional<CanalSatData> CanalSatBaseProtocol::decode(RemoteReceiveData src) {
|
||||
|
||||
void CanalSatBaseProtocol::dump(const CanalSatData &data) {
|
||||
if (this->tag_ == CANALSATLD_TAG) {
|
||||
ESP_LOGI(this->tag_, "Received CanalSatLD: device=0x%02X, address=0x%02X, command=0x%02X, repeat=0x%X", data.device,
|
||||
ESP_LOGD(this->tag_, "Received CanalSatLD: device=0x%02X, address=0x%02X, command=0x%02X, repeat=0x%X", data.device,
|
||||
data.address, data.command, data.repeat);
|
||||
} else {
|
||||
ESP_LOGI(this->tag_, "Received CanalSat: device=0x%02X, address=0x%02X, command=0x%02X, repeat=0x%X", data.device,
|
||||
ESP_LOGD(this->tag_, "Received CanalSat: device=0x%02X, address=0x%02X, command=0x%02X, repeat=0x%X", data.device,
|
||||
data.address, data.command, data.repeat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,11 +101,11 @@ optional<CoolixData> CoolixProtocol::decode(RemoteReceiveData data) {
|
||||
|
||||
void CoolixProtocol::dump(const CoolixData &data) {
|
||||
if (data.is_strict()) {
|
||||
ESP_LOGI(TAG, "Received Coolix: 0x%06X", data.first);
|
||||
ESP_LOGD(TAG, "Received Coolix: 0x%06X", data.first);
|
||||
} else if (data.has_second()) {
|
||||
ESP_LOGI(TAG, "Received unstrict Coolix: [0x%06X, 0x%06X]", data.first, data.second);
|
||||
ESP_LOGD(TAG, "Received unstrict Coolix: [0x%06X, 0x%06X]", data.first, data.second);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Received unstrict Coolix: [0x%06X]", data.first);
|
||||
ESP_LOGD(TAG, "Received unstrict Coolix: [0x%06X]", data.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ optional<DishData> DishProtocol::decode(RemoteReceiveData src) {
|
||||
}
|
||||
|
||||
void DishProtocol::dump(const DishData &data) {
|
||||
ESP_LOGI(TAG, "Received Dish: address=0x%02X, command=0x%02X", data.address, data.command);
|
||||
ESP_LOGD(TAG, "Received Dish: address=0x%02X, command=0x%02X", data.address, data.command);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -205,7 +205,7 @@ optional<DraytonData> DraytonProtocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void DraytonProtocol::dump(const DraytonData &data) {
|
||||
ESP_LOGI(TAG, "Received Drayton: address=0x%04X (0x%04x), channel=0x%03x command=0x%03X", data.address,
|
||||
ESP_LOGD(TAG, "Received Drayton: address=0x%04X (0x%04x), channel=0x%03x command=0x%03X", data.address,
|
||||
((data.address << 1) & 0xffff), data.channel, data.command);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ optional<JVCData> JVCProtocol::decode(RemoteReceiveData src) {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
void JVCProtocol::dump(const JVCData &data) { ESP_LOGI(TAG, "Received JVC: data=0x%04X", data.data); }
|
||||
void JVCProtocol::dump(const JVCData &data) { ESP_LOGD(TAG, "Received JVC: data=0x%04X", data.data); }
|
||||
|
||||
} // namespace remote_base
|
||||
} // namespace esphome
|
||||
|
||||
@@ -51,7 +51,7 @@ optional<LGData> LGProtocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void LGProtocol::dump(const LGData &data) {
|
||||
ESP_LOGI(TAG, "Received LG: data=0x%08X, nbits=%d", data.data, data.nbits);
|
||||
ESP_LOGD(TAG, "Received LG: data=0x%08X, nbits=%d", data.data, data.nbits);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -76,7 +76,7 @@ optional<MagiQuestData> MagiQuestProtocol::decode(RemoteReceiveData src) {
|
||||
return data;
|
||||
}
|
||||
void MagiQuestProtocol::dump(const MagiQuestData &data) {
|
||||
ESP_LOGI(TAG, "Received MagiQuest: wand_id=0x%08X, magnitude=0x%04X", data.wand_id, data.magnitude);
|
||||
ESP_LOGD(TAG, "Received MagiQuest: wand_id=0x%08X, magnitude=0x%04X", data.wand_id, data.magnitude);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -70,7 +70,7 @@ optional<MideaData> MideaProtocol::decode(RemoteReceiveData src) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void MideaProtocol::dump(const MideaData &data) { ESP_LOGI(TAG, "Received Midea: %s", data.to_string().c_str()); }
|
||||
void MideaProtocol::dump(const MideaData &data) { ESP_LOGD(TAG, "Received Midea: %s", data.to_string().c_str()); }
|
||||
|
||||
} // namespace remote_base
|
||||
} // namespace esphome
|
||||
|
||||
@@ -67,7 +67,7 @@ optional<NECData> NECProtocol::decode(RemoteReceiveData src) {
|
||||
return data;
|
||||
}
|
||||
void NECProtocol::dump(const NECData &data) {
|
||||
ESP_LOGI(TAG, "Received NEC: address=0x%04X, command=0x%04X", data.address, data.command);
|
||||
ESP_LOGD(TAG, "Received NEC: address=0x%04X, command=0x%04X", data.address, data.command);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -232,7 +232,7 @@ optional<NexaData> NexaProtocol::decode(RemoteReceiveData src) {
|
||||
}
|
||||
|
||||
void NexaProtocol::dump(const NexaData &data) {
|
||||
ESP_LOGI(TAG, "Received NEXA: device=0x%04X group=%d state=%d channel=%d level=%d", data.device, data.group,
|
||||
ESP_LOGD(TAG, "Received NEXA: device=0x%04X group=%d state=%d channel=%d level=%d", data.device, data.group,
|
||||
data.state, data.channel, data.level);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ optional<PanasonicData> PanasonicProtocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void PanasonicProtocol::dump(const PanasonicData &data) {
|
||||
ESP_LOGI(TAG, "Received Panasonic: address=0x%04X, command=0x%08X", data.address, data.command);
|
||||
ESP_LOGD(TAG, "Received Panasonic: address=0x%04X, command=0x%08X", data.address, data.command);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -146,9 +146,9 @@ optional<PioneerData> PioneerProtocol::decode(RemoteReceiveData src) {
|
||||
}
|
||||
void PioneerProtocol::dump(const PioneerData &data) {
|
||||
if (data.rc_code_2 == 0) {
|
||||
ESP_LOGI(TAG, "Received Pioneer: rc_code_X=0x%04X", data.rc_code_1);
|
||||
ESP_LOGD(TAG, "Received Pioneer: rc_code_X=0x%04X", data.rc_code_1);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Received Pioneer: rc_code_1=0x%04X, rc_code_2=0x%04X", data.rc_code_1, data.rc_code_2);
|
||||
ESP_LOGD(TAG, "Received Pioneer: rc_code_1=0x%04X, rc_code_2=0x%04X", data.rc_code_1, data.rc_code_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -234,9 +234,9 @@ void ProntoProtocol::dump(const ProntoData &data) {
|
||||
first = data.data.substr(0, 229);
|
||||
rest = data.data.substr(230);
|
||||
}
|
||||
ESP_LOGI(TAG, "Received Pronto: data=%s", first.c_str());
|
||||
ESP_LOGD(TAG, "Received Pronto: data=%s", first.c_str());
|
||||
if (!rest.empty()) {
|
||||
ESP_LOGI(TAG, "%s", rest.c_str());
|
||||
ESP_LOGD(TAG, "%s", rest.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ bool RawDumper::dump(RemoteReceiveData src) {
|
||||
if (written < 0 || written >= int(remaining_length)) {
|
||||
// write failed, flush...
|
||||
buffer[buffer_offset] = '\0';
|
||||
ESP_LOGI(TAG, "%s", buffer);
|
||||
ESP_LOGD(TAG, "%s", buffer);
|
||||
buffer_offset = 0;
|
||||
written = sprintf(buffer, " ");
|
||||
if (i + 1 < src.size()) {
|
||||
@@ -38,7 +38,7 @@ bool RawDumper::dump(RemoteReceiveData src) {
|
||||
buffer_offset += written;
|
||||
}
|
||||
if (buffer_offset != 0) {
|
||||
ESP_LOGI(TAG, "%s", buffer);
|
||||
ESP_LOGD(TAG, "%s", buffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ optional<RC5Data> RC5Protocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void RC5Protocol::dump(const RC5Data &data) {
|
||||
ESP_LOGI(TAG, "Received RC5: address=0x%02X, command=0x%02X", data.address, data.command);
|
||||
ESP_LOGD(TAG, "Received RC5: address=0x%02X, command=0x%02X", data.address, data.command);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -173,7 +173,7 @@ optional<RC6Data> RC6Protocol::decode(RemoteReceiveData src) {
|
||||
}
|
||||
|
||||
void RC6Protocol::dump(const RC6Data &data) {
|
||||
ESP_LOGI(RC6_TAG, "Received RC6: mode=0x%X, address=0x%02X, command=0x%02X, toggle=0x%X", data.mode, data.address,
|
||||
ESP_LOGD(RC6_TAG, "Received RC6: mode=0x%X, address=0x%02X, command=0x%02X, toggle=0x%X", data.mode, data.address,
|
||||
data.command, data.toggle);
|
||||
}
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ bool RCSwitchDumper::dump(RemoteReceiveData src) {
|
||||
buffer[j] = (out_data & ((uint64_t) 1 << (out_nbits - j - 1))) ? '1' : '0';
|
||||
|
||||
buffer[out_nbits] = '\0';
|
||||
ESP_LOGI(TAG, "Received RCSwitch Raw: protocol=%u data='%s'", i, buffer);
|
||||
ESP_LOGD(TAG, "Received RCSwitch Raw: protocol=%u data='%s'", i, buffer);
|
||||
|
||||
// only send first decoded protocol
|
||||
return true;
|
||||
|
||||
@@ -96,7 +96,7 @@ optional<Samsung36Data> Samsung36Protocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void Samsung36Protocol::dump(const Samsung36Data &data) {
|
||||
ESP_LOGI(TAG, "Received Samsung36: address=0x%04X, command=0x%08X", data.address, data.command);
|
||||
ESP_LOGD(TAG, "Received Samsung36: address=0x%04X, command=0x%08X", data.address, data.command);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -58,7 +58,7 @@ optional<SamsungData> SamsungProtocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void SamsungProtocol::dump(const SamsungData &data) {
|
||||
ESP_LOGI(TAG, "Received Samsung: data=0x%" PRIX64 ", nbits=%d", data.data, data.nbits);
|
||||
ESP_LOGD(TAG, "Received Samsung: data=0x%" PRIX64 ", nbits=%d", data.data, data.nbits);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -62,7 +62,7 @@ optional<SonyData> SonyProtocol::decode(RemoteReceiveData src) {
|
||||
return out;
|
||||
}
|
||||
void SonyProtocol::dump(const SonyData &data) {
|
||||
ESP_LOGI(TAG, "Received Sony: data=0x%08X, nbits=%d", data.data, data.nbits);
|
||||
ESP_LOGD(TAG, "Received Sony: data=0x%08X, nbits=%d", data.data, data.nbits);
|
||||
}
|
||||
|
||||
} // namespace remote_base
|
||||
|
||||
@@ -105,9 +105,9 @@ optional<ToshibaAcData> ToshibaAcProtocol::decode(RemoteReceiveData src) {
|
||||
|
||||
void ToshibaAcProtocol::dump(const ToshibaAcData &data) {
|
||||
if (data.rc_code_2 != 0) {
|
||||
ESP_LOGI(TAG, "Received Toshiba AC: rc_code_1=0x%" PRIX64 ", rc_code_2=0x%" PRIX64, data.rc_code_1, data.rc_code_2);
|
||||
ESP_LOGD(TAG, "Received Toshiba AC: rc_code_1=0x%" PRIX64 ", rc_code_2=0x%" PRIX64, data.rc_code_1, data.rc_code_2);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Received Toshiba AC: rc_code_1=0x%" PRIX64, data.rc_code_1);
|
||||
ESP_LOGD(TAG, "Received Toshiba AC: rc_code_1=0x%" PRIX64, data.rc_code_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,14 +100,14 @@ bool check_sml_data(const bytes &buffer) {
|
||||
}
|
||||
|
||||
uint16_t crc_received = (buffer.at(buffer.size() - 2) << 8) | buffer.at(buffer.size() - 1);
|
||||
uint16_t crc_calculated = crc16(buffer.data(), buffer.size() - 2, 0x6e23, 0x8408, true, true);
|
||||
uint16_t crc_calculated = crc16(buffer.data(), buffer.size(), 0x6e23, 0x8408, true, true);
|
||||
crc_calculated = (crc_calculated >> 8) | (crc_calculated << 8);
|
||||
if (crc_received == crc_calculated) {
|
||||
ESP_LOGV(TAG, "Checksum verification successful with CRC16/X25.");
|
||||
return true;
|
||||
}
|
||||
|
||||
crc_calculated = crc16(buffer.data(), buffer.size() - 2, 0xed50, 0x8408);
|
||||
crc_calculated = crc16(buffer.data(), buffer.size(), 0xed50, 0x8408);
|
||||
if (crc_received == crc_calculated) {
|
||||
ESP_LOGV(TAG, "Checksum verification successful with CRC16/KERMIT.");
|
||||
return true;
|
||||
|
||||
@@ -87,7 +87,25 @@ class BSDSocketImpl : public Socket {
|
||||
int listen(int backlog) override { return ::listen(fd_, backlog); }
|
||||
ssize_t read(void *buf, size_t len) override { return ::read(fd_, buf, len); }
|
||||
ssize_t readv(const struct iovec *iov, int iovcnt) override {
|
||||
#if defined(USE_ESP32)
|
||||
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 4
|
||||
// esp-idf v3 doesn't have readv, emulate it
|
||||
ssize_t ret = 0;
|
||||
for (int i = 0; i < iovcnt; i++) {
|
||||
ssize_t err = this->read(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len);
|
||||
if (err == -1) {
|
||||
if (ret != 0) {
|
||||
// if we already read some don't return an error
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
ret += err;
|
||||
if (err != iov[i].iov_len)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
#elif defined(USE_ESP32)
|
||||
// ESP-IDF v4 only has symbol lwip_readv
|
||||
return ::lwip_readv(fd_, iov, iovcnt);
|
||||
#else
|
||||
return ::readv(fd_, iov, iovcnt);
|
||||
@@ -96,7 +114,26 @@ class BSDSocketImpl : public Socket {
|
||||
ssize_t write(const void *buf, size_t len) override { return ::write(fd_, buf, len); }
|
||||
ssize_t send(void *buf, size_t len, int flags) { return ::send(fd_, buf, len, flags); }
|
||||
ssize_t writev(const struct iovec *iov, int iovcnt) override {
|
||||
#if defined(USE_ESP32)
|
||||
#if defined(USE_ESP32) && ESP_IDF_VERSION_MAJOR < 4
|
||||
// esp-idf v3 doesn't have writev, emulate it
|
||||
ssize_t ret = 0;
|
||||
for (int i = 0; i < iovcnt; i++) {
|
||||
ssize_t err =
|
||||
this->send(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len, i == iovcnt - 1 ? 0 : MSG_MORE);
|
||||
if (err == -1) {
|
||||
if (ret != 0) {
|
||||
// if we already wrote some don't return an error
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
ret += err;
|
||||
if (err != iov[i].iov_len)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
#elif defined(USE_ESP32)
|
||||
// ESP-IDF v4 only has symbol lwip_writev
|
||||
return ::lwip_writev(fd_, iov, iovcnt);
|
||||
#else
|
||||
return ::writev(fd_, iov, iovcnt);
|
||||
|
||||
@@ -23,9 +23,7 @@ SPI_DATA_RATE_OPTIONS = {
|
||||
40e6: SPIDataRate.DATA_RATE_40MHZ,
|
||||
20e6: SPIDataRate.DATA_RATE_20MHZ,
|
||||
10e6: SPIDataRate.DATA_RATE_10MHZ,
|
||||
8e6: SPIDataRate.DATA_RATE_8MHZ,
|
||||
5e6: SPIDataRate.DATA_RATE_5MHZ,
|
||||
4e6: SPIDataRate.DATA_RATE_4MHZ,
|
||||
2e6: SPIDataRate.DATA_RATE_2MHZ,
|
||||
1e6: SPIDataRate.DATA_RATE_1MHZ,
|
||||
2e5: SPIDataRate.DATA_RATE_200KHZ,
|
||||
|
||||
@@ -76,8 +76,7 @@ void SPIComponent::setup() {
|
||||
if (spi_bus_num == 0) {
|
||||
this->hw_spi_ = &SPI;
|
||||
} else {
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
this->hw_spi_ = new SPIClass(FSPI); // NOLINT(cppcoreguidelines-owning-memory)
|
||||
#else
|
||||
this->hw_spi_ = new SPIClass(HSPI); // NOLINT(cppcoreguidelines-owning-memory)
|
||||
|
||||
@@ -63,7 +63,6 @@ enum SPIDataRate : uint32_t {
|
||||
DATA_RATE_1MHZ = 1000000,
|
||||
DATA_RATE_2MHZ = 2000000,
|
||||
DATA_RATE_4MHZ = 4000000,
|
||||
DATA_RATE_5MHZ = 5000000,
|
||||
DATA_RATE_8MHZ = 8000000,
|
||||
DATA_RATE_10MHZ = 10000000,
|
||||
DATA_RATE_20MHZ = 20000000,
|
||||
|
||||
@@ -132,7 +132,7 @@ void SSD1306::setup() {
|
||||
this->command(SSD1306_COMMAND_DISPLAY_ALL_ON_RESUME);
|
||||
|
||||
// Inverse display mode (0xA6, 0xA7)
|
||||
this->set_invert(this->invert_);
|
||||
this->command(SSD1306_COMMAND_NORMAL_DISPLAY | this->invert_);
|
||||
|
||||
// Disable scrolling mode (0x2E)
|
||||
this->command(SSD1306_COMMAND_DEACTIVATE_SCROLL);
|
||||
@@ -190,12 +190,6 @@ void SSD1306::update() {
|
||||
this->do_update_();
|
||||
this->display();
|
||||
}
|
||||
|
||||
void SSD1306::set_invert(bool invert) {
|
||||
this->invert_ = invert;
|
||||
// Inverse display mode (0xA6, 0xA7)
|
||||
this->command(SSD1306_COMMAND_NORMAL_DISPLAY | this->invert_);
|
||||
}
|
||||
void SSD1306::set_contrast(float contrast) {
|
||||
// validation
|
||||
this->contrast_ = clamp(contrast, 0.0F, 1.0F);
|
||||
|
||||
@@ -43,7 +43,6 @@ class SSD1306 : public PollingComponent, public display::DisplayBuffer {
|
||||
void init_offset_x(uint8_t offset_x) { this->offset_x_ = offset_x; }
|
||||
void init_offset_y(uint8_t offset_y) { this->offset_y_ = offset_y; }
|
||||
void init_invert(bool invert) { this->invert_ = invert; }
|
||||
void set_invert(bool invert);
|
||||
bool is_on();
|
||||
void turn_on();
|
||||
void turn_off();
|
||||
|
||||
@@ -591,11 +591,11 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_DEFAULT_TARGET_TEMPERATURE_LOW): cv.temperature,
|
||||
cv.Optional(
|
||||
CONF_SET_POINT_MINIMUM_DIFFERENTIAL, default=0.5
|
||||
): cv.temperature_delta,
|
||||
cv.Optional(CONF_COOL_DEADBAND, default=0.5): cv.temperature_delta,
|
||||
cv.Optional(CONF_COOL_OVERRUN, default=0.5): cv.temperature_delta,
|
||||
cv.Optional(CONF_HEAT_DEADBAND, default=0.5): cv.temperature_delta,
|
||||
cv.Optional(CONF_HEAT_OVERRUN, default=0.5): cv.temperature_delta,
|
||||
): cv.temperature,
|
||||
cv.Optional(CONF_COOL_DEADBAND, default=0.5): cv.temperature,
|
||||
cv.Optional(CONF_COOL_OVERRUN, default=0.5): cv.temperature,
|
||||
cv.Optional(CONF_HEAT_DEADBAND, default=0.5): cv.temperature,
|
||||
cv.Optional(CONF_HEAT_OVERRUN, default=0.5): cv.temperature,
|
||||
cv.Optional(CONF_MAX_COOLING_RUN_TIME): cv.positive_time_period_seconds,
|
||||
cv.Optional(CONF_MAX_HEATING_RUN_TIME): cv.positive_time_period_seconds,
|
||||
cv.Optional(CONF_MIN_COOLING_OFF_TIME): cv.positive_time_period_seconds,
|
||||
@@ -608,8 +608,8 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_MIN_HEATING_OFF_TIME): cv.positive_time_period_seconds,
|
||||
cv.Optional(CONF_MIN_HEATING_RUN_TIME): cv.positive_time_period_seconds,
|
||||
cv.Required(CONF_MIN_IDLE_TIME): cv.positive_time_period_seconds,
|
||||
cv.Optional(CONF_SUPPLEMENTAL_COOLING_DELTA): cv.temperature_delta,
|
||||
cv.Optional(CONF_SUPPLEMENTAL_HEATING_DELTA): cv.temperature_delta,
|
||||
cv.Optional(CONF_SUPPLEMENTAL_COOLING_DELTA): cv.temperature,
|
||||
cv.Optional(CONF_SUPPLEMENTAL_HEATING_DELTA): cv.temperature,
|
||||
cv.Optional(
|
||||
CONF_FAN_ONLY_ACTION_USES_FAN_MODE_TIMER, default=False
|
||||
): cv.boolean,
|
||||
|
||||
@@ -324,7 +324,11 @@ class WiFiComponent : public Component {
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
void wifi_event_callback_(arduino_event_id_t event, arduino_event_info_t info);
|
||||
#else
|
||||
void wifi_event_callback_(system_event_id_t event, system_event_info_t info);
|
||||
#endif
|
||||
void wifi_scan_done_callback_();
|
||||
#endif
|
||||
#ifdef USE_ESP_IDF
|
||||
|
||||
@@ -203,10 +203,12 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
// Units: AP beacon intervals. Defaults to 3 if set to 0.
|
||||
conf.sta.listen_interval = 0;
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
// Protected Management Frame
|
||||
// Device will prefer to connect in PMF mode if other device also advertises PMF capability.
|
||||
conf.sta.pmf_cfg.capable = true;
|
||||
conf.sta.pmf_cfg.required = false;
|
||||
#endif
|
||||
|
||||
// note, we do our own filtering
|
||||
// The minimum rssi to accept in the fast scan mode
|
||||
@@ -312,7 +314,11 @@ const char *get_auth_mode_str(uint8_t mode) {
|
||||
}
|
||||
}
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
using esphome_ip4_addr_t = esp_ip4_addr_t;
|
||||
#else
|
||||
using esphome_ip4_addr_t = ip4_addr_t;
|
||||
#endif
|
||||
|
||||
std::string format_ip4_addr(const esphome_ip4_addr_t &ip) {
|
||||
char buf[20];
|
||||
@@ -398,6 +404,8 @@ const char *get_disconnect_reason_str(uint8_t reason) {
|
||||
}
|
||||
}
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
|
||||
#define ESPHOME_EVENT_ID_WIFI_READY ARDUINO_EVENT_WIFI_READY
|
||||
#define ESPHOME_EVENT_ID_WIFI_SCAN_DONE ARDUINO_EVENT_WIFI_SCAN_DONE
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_START ARDUINO_EVENT_WIFI_STA_START
|
||||
@@ -418,6 +426,28 @@ const char *get_disconnect_reason_str(uint8_t reason) {
|
||||
using esphome_wifi_event_id_t = arduino_event_id_t;
|
||||
using esphome_wifi_event_info_t = arduino_event_info_t;
|
||||
|
||||
#else // ESP_IDF_VERSION_MAJOR >= 4
|
||||
|
||||
#define ESPHOME_EVENT_ID_WIFI_READY SYSTEM_EVENT_WIFI_READY
|
||||
#define ESPHOME_EVENT_ID_WIFI_SCAN_DONE SYSTEM_EVENT_SCAN_DONE
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_START SYSTEM_EVENT_STA_START
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_STOP SYSTEM_EVENT_STA_STOP
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_CONNECTED SYSTEM_EVENT_STA_CONNECTED
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED SYSTEM_EVENT_STA_DISCONNECTED
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE SYSTEM_EVENT_STA_AUTHMODE_CHANGE
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_GOT_IP SYSTEM_EVENT_STA_GOT_IP
|
||||
#define ESPHOME_EVENT_ID_WIFI_STA_LOST_IP SYSTEM_EVENT_STA_LOST_IP
|
||||
#define ESPHOME_EVENT_ID_WIFI_AP_START SYSTEM_EVENT_AP_START
|
||||
#define ESPHOME_EVENT_ID_WIFI_AP_STOP SYSTEM_EVENT_AP_STOP
|
||||
#define ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED SYSTEM_EVENT_AP_STACONNECTED
|
||||
#define ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED SYSTEM_EVENT_AP_STADISCONNECTED
|
||||
#define ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED SYSTEM_EVENT_AP_STAIPASSIGNED
|
||||
#define ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED SYSTEM_EVENT_AP_PROBEREQRECVED
|
||||
using esphome_wifi_event_id_t = system_event_id_t;
|
||||
using esphome_wifi_event_info_t = system_event_info_t;
|
||||
|
||||
#endif // !(ESP_IDF_VERSION_MAJOR >= 4)
|
||||
|
||||
void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_wifi_event_info_t info) {
|
||||
switch (event) {
|
||||
case ESPHOME_EVENT_ID_WIFI_READY: {
|
||||
@@ -425,7 +455,11 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_SCAN_DONE: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_scan_done;
|
||||
#else
|
||||
auto it = info.scan_done;
|
||||
#endif
|
||||
ESP_LOGV(TAG, "Event: WiFi Scan Done status=%u number=%u scan_id=%u", it.status, it.number, it.scan_id);
|
||||
|
||||
this->wifi_scan_done_callback_();
|
||||
@@ -441,20 +475,28 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_sta_connected;
|
||||
#else
|
||||
auto it = info.connected;
|
||||
#endif
|
||||
char buf[33];
|
||||
memcpy(buf, it.ssid, it.ssid_len);
|
||||
buf[it.ssid_len] = '\0';
|
||||
ESP_LOGV(TAG, "Event: Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf,
|
||||
format_mac_addr(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode));
|
||||
#if LWIP_IPV6
|
||||
this->set_timeout(100, [] { WiFi.enableIpV6(); });
|
||||
WiFi.enableIpV6();
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_sta_disconnected;
|
||||
#else
|
||||
auto it = info.disconnected;
|
||||
#endif
|
||||
char buf[33];
|
||||
memcpy(buf, it.ssid, it.ssid_len);
|
||||
buf[it.ssid_len] = '\0';
|
||||
@@ -480,7 +522,11 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_sta_authmode_change;
|
||||
#else
|
||||
auto it = info.auth_change;
|
||||
#endif
|
||||
ESP_LOGV(TAG, "Event: Authmode Change old=%s new=%s", get_auth_mode_str(it.old_mode),
|
||||
get_auth_mode_str(it.new_mode));
|
||||
// Mitigate CVE-2020-12638
|
||||
@@ -524,14 +570,24 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_sta_connected;
|
||||
auto &mac = it.bssid;
|
||||
#else
|
||||
auto it = info.sta_connected;
|
||||
auto &mac = it.mac;
|
||||
#endif
|
||||
ESP_LOGV(TAG, "Event: AP client connected MAC=%s", format_mac_addr(mac).c_str());
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_sta_disconnected;
|
||||
auto &mac = it.bssid;
|
||||
#else
|
||||
auto it = info.sta_disconnected;
|
||||
auto &mac = it.mac;
|
||||
#endif
|
||||
ESP_LOGV(TAG, "Event: AP client disconnected MAC=%s", format_mac_addr(mac).c_str());
|
||||
break;
|
||||
}
|
||||
@@ -540,7 +596,11 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED: {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
auto it = info.wifi_ap_probereqrecved;
|
||||
#else
|
||||
auto it = info.ap_probereqrecved;
|
||||
#endif
|
||||
ESP_LOGVV(TAG, "Event: AP receive Probe Request MAC=%s RSSI=%d", format_mac_addr(it.mac).c_str(), it.rssi);
|
||||
break;
|
||||
}
|
||||
@@ -682,7 +742,10 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
strncpy(reinterpret_cast<char *>(conf.ap.password), ap.get_password().c_str(), sizeof(conf.ap.ssid));
|
||||
}
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
// pairwise cipher of SoftAP, group cipher will be derived using this.
|
||||
conf.ap.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP;
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_wifi_set_config(WIFI_IF_AP, &conf);
|
||||
if (err != ESP_OK) {
|
||||
|
||||
@@ -312,10 +312,12 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
// Units: AP beacon intervals. Defaults to 3 if set to 0.
|
||||
conf.sta.listen_interval = 0;
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
// Protected Management Frame
|
||||
// Device will prefer to connect in PMF mode if other device also advertises PMF capability.
|
||||
conf.sta.pmf_cfg.capable = true;
|
||||
conf.sta.pmf_cfg.required = false;
|
||||
#endif
|
||||
|
||||
// note, we do our own filtering
|
||||
// The minimum rssi to accept in the fast scan mode
|
||||
@@ -836,8 +838,10 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
strncpy(reinterpret_cast<char *>(conf.ap.password), ap.get_password().c_str(), sizeof(conf.ap.password));
|
||||
}
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
// pairwise cipher of SoftAP, group cipher will be derived using this.
|
||||
conf.ap.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP;
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_wifi_set_config(WIFI_IF_AP, &conf);
|
||||
if (err != ESP_OK) {
|
||||
|
||||
@@ -125,7 +125,6 @@ RESERVED_IDS = [
|
||||
"char16_t",
|
||||
"char32_t",
|
||||
"class",
|
||||
"clock",
|
||||
"compl",
|
||||
"concept",
|
||||
"const",
|
||||
@@ -929,27 +928,6 @@ def temperature(value):
|
||||
raise err
|
||||
|
||||
|
||||
def temperature_delta(value):
|
||||
err = None
|
||||
try:
|
||||
return _temperature_c(value)
|
||||
except Invalid as orig_err:
|
||||
err = orig_err
|
||||
|
||||
try:
|
||||
return _temperature_k(value)
|
||||
except Invalid:
|
||||
pass
|
||||
|
||||
try:
|
||||
fahrenheit = _temperature_f(value)
|
||||
return fahrenheit * (5 / 9)
|
||||
except Invalid:
|
||||
pass
|
||||
|
||||
raise err
|
||||
|
||||
|
||||
_color_temperature_mireds = float_with_unit("Color Temperature", r"(mireds|Mireds)")
|
||||
_color_temperature_kelvin = float_with_unit("Color Temperature", r"(K|Kelvin)")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Constants used by esphome."""
|
||||
|
||||
__version__ = "2023.9.0-dev"
|
||||
__version__ = "2023.8.0b3"
|
||||
|
||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
// IDF-specific feature flags
|
||||
#ifdef USE_ESP_IDF
|
||||
#define USE_MQTT_IDF_ENQUEUE
|
||||
#define USE_ESP_ADF
|
||||
#endif
|
||||
|
||||
// ESP32-specific feature flags
|
||||
|
||||
@@ -868,6 +868,9 @@ class PingStatusThread(threading.Thread):
|
||||
entries = _list_dashboard_entries()
|
||||
queue = collections.deque()
|
||||
for entry in entries:
|
||||
if entry.no_mdns is True:
|
||||
continue
|
||||
|
||||
if entry.address is None:
|
||||
PING_RESULT[entry.filename] = None
|
||||
continue
|
||||
|
||||
@@ -64,7 +64,7 @@ lib_deps =
|
||||
glmnet/Dsmr@0.7 ; dsmr
|
||||
rweather/Crypto@0.4.0 ; dsmr
|
||||
dudanov/MideaUART@1.1.8 ; midea
|
||||
tonia/HeatpumpIR@1.0.23 ; heatpumpir
|
||||
tonia/HeatpumpIR@1.0.20 ; heatpumpir
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
-DUSE_ARDUINO
|
||||
|
||||
@@ -6,12 +6,12 @@ tornado==6.3.2
|
||||
tzlocal==5.0.1 # from time
|
||||
tzdata>=2021.1 # from time
|
||||
pyserial==3.5
|
||||
platformio==6.1.10 # When updating platformio, also update Dockerfile
|
||||
platformio==6.1.9 # When updating platformio, also update Dockerfile
|
||||
esptool==4.6.2
|
||||
click==8.1.7
|
||||
click==8.1.6
|
||||
esphome-dashboard==20230711.0
|
||||
aioesphomeapi==15.0.0
|
||||
zeroconf==0.80.0
|
||||
zeroconf==0.74.0
|
||||
|
||||
# esp-idf requires this, but doesn't bundle it by default
|
||||
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24
|
||||
|
||||
@@ -348,16 +348,6 @@ mcp23s17:
|
||||
deviceaddress: 1
|
||||
|
||||
sensor:
|
||||
- platform: pmwcs3
|
||||
i2c_id: i2c_bus
|
||||
e25:
|
||||
name: pmwcs3_e25
|
||||
ec:
|
||||
name: pmwcs3_ec
|
||||
temperature:
|
||||
name: pmwcs3_temperature
|
||||
vwc:
|
||||
name: pmwcs3_vwc
|
||||
- platform: gcja5
|
||||
pm_1_0:
|
||||
name: "Particulate Matter <1.0µm Concentration"
|
||||
@@ -2299,13 +2289,6 @@ climate:
|
||||
name: HeatpumpIR Climate
|
||||
min_temperature: 18
|
||||
max_temperature: 30
|
||||
- platform: heatpumpir
|
||||
protocol: greeyt
|
||||
horizontal_default: left
|
||||
vertical_default: up
|
||||
name: HeatpumpIR Climate
|
||||
min_temperature: 18
|
||||
max_temperature: 30
|
||||
- platform: midea_ir
|
||||
name: Midea IR
|
||||
use_fahrenheit: true
|
||||
|
||||
@@ -768,8 +768,3 @@ switch:
|
||||
characteristic_uuid: 6490FAFE-0734-732C-8705-91B653A081FC
|
||||
value: !lambda |-
|
||||
return {0x13, 0x37};
|
||||
|
||||
|
||||
esp32_ble_server:
|
||||
id: ble
|
||||
manufacturer_data: [0x72, 0x4, 0x00, 0x23]
|
||||
|
||||
@@ -957,7 +957,7 @@ climate:
|
||||
temperature_step: 1 °C
|
||||
supported_modes:
|
||||
- 'OFF'
|
||||
- HEAT_COOL
|
||||
- AUTO
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
|
||||
Reference in New Issue
Block a user