esphome 2024.6.6__py3-none-any.whl → 2024.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/components/aht10/aht10.cpp +4 -2
- esphome/components/climate/climate.cpp +10 -6
- esphome/components/climate/climate_traits.h +3 -3
- esphome/components/cover/cover.h +2 -2
- esphome/components/esp32_camera/__init__.py +6 -3
- esphome/components/esp32_can/canbus.py +3 -0
- esphome/components/ethernet/ethernet_component.cpp +8 -3
- esphome/components/font/__init__.py +2 -28
- esphome/components/gree/climate.py +1 -0
- esphome/components/gree/gree.cpp +11 -3
- esphome/components/gree/gree.h +5 -1
- esphome/components/haier/binary_sensor/__init__.py +4 -4
- esphome/components/haier/button/__init__.py +1 -1
- esphome/components/haier/climate.py +43 -9
- esphome/components/haier/haier_base.cpp +4 -0
- esphome/components/haier/haier_base.h +11 -1
- esphome/components/haier/hon_climate.cpp +109 -55
- esphome/components/haier/hon_climate.h +7 -1
- esphome/components/haier/hon_packet.h +5 -0
- esphome/components/haier/sensor/__init__.py +5 -5
- esphome/components/haier/smartair2_climate.cpp +1 -0
- esphome/components/haier/text_sensor/__init__.py +4 -4
- esphome/components/heatpumpir/climate.py +12 -5
- esphome/components/heatpumpir/heatpumpir.cpp +11 -0
- esphome/components/heatpumpir/heatpumpir.h +11 -0
- esphome/components/http_request/http_request_arduino.cpp +7 -2
- esphome/components/http_request/update/http_request_update.cpp +6 -7
- esphome/components/http_request/update/http_request_update.h +0 -3
- esphome/components/i2s_audio/__init__.py +10 -0
- esphome/components/i2s_audio/microphone/__init__.py +7 -0
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +2 -3
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +3 -0
- esphome/components/image/__init__.py +2 -29
- esphome/components/improv_serial/improv_serial_component.cpp +9 -8
- esphome/components/ltr390/ltr390.cpp +44 -29
- esphome/components/ltr390/ltr390.h +9 -5
- esphome/components/ltr390/sensor.py +35 -5
- esphome/components/mdns/__init__.py +3 -3
- esphome/components/mdns/mdns_component.cpp +3 -1
- esphome/components/mdns/mdns_component.h +3 -1
- esphome/components/mdns/mdns_esp32.cpp +2 -1
- esphome/components/mdns/mdns_esp8266.cpp +2 -1
- esphome/components/mdns/mdns_host.cpp +2 -1
- esphome/components/mdns/mdns_libretiny.cpp +2 -1
- esphome/components/mdns/mdns_rp2040.cpp +2 -1
- esphome/components/micro_wake_word/__init__.py +205 -56
- esphome/components/micro_wake_word/micro_wake_word.cpp +225 -275
- esphome/components/micro_wake_word/micro_wake_word.h +77 -107
- esphome/components/micro_wake_word/preprocessor_settings.h +20 -0
- esphome/components/micro_wake_word/streaming_model.cpp +189 -0
- esphome/components/micro_wake_word/streaming_model.h +84 -0
- esphome/components/mitsubishi/mitsubishi.cpp +1 -0
- esphome/components/modbus_controller/text_sensor/__init__.py +2 -1
- esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +4 -1
- esphome/components/modbus_controller/text_sensor/modbus_textsensor.h +1 -1
- esphome/components/number/__init__.py +2 -0
- esphome/components/ota/ota_backend_arduino_esp32.cpp +22 -7
- esphome/components/ota/ota_backend_arduino_esp8266.cpp +23 -8
- esphome/components/ota/ota_backend_arduino_libretiny.cpp +22 -7
- esphome/components/ota/ota_backend_arduino_rp2040.cpp +22 -7
- esphome/components/pmsa003i/pmsa003i.cpp +9 -0
- esphome/components/qspi_amoled/display.py +16 -4
- esphome/components/qspi_amoled/qspi_amoled.cpp +16 -0
- esphome/components/qspi_amoled/qspi_amoled.h +0 -3
- esphome/components/remote_base/dooya_protocol.cpp +4 -4
- esphome/components/remote_base/rc_switch_protocol.cpp +1 -1
- esphome/components/restart/button/__init__.py +2 -0
- esphome/components/script/__init__.py +1 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/tuya/tuya.cpp +8 -2
- esphome/components/tuya/tuya.h +3 -1
- esphome/components/uart/__init__.py +72 -9
- esphome/components/uart/uart_component_esp32_arduino.cpp +18 -4
- esphome/components/uart/uart_component_esp_idf.cpp +22 -2
- esphome/components/uart/uart_component_host.cpp +295 -0
- esphome/components/uart/uart_component_host.h +38 -0
- esphome/components/uptime/sensor.py +44 -11
- esphome/components/uptime/{uptime_sensor.cpp → uptime_seconds_sensor.cpp} +11 -7
- esphome/components/uptime/{uptime_sensor.h → uptime_seconds_sensor.h} +2 -2
- esphome/components/uptime/uptime_timestamp_sensor.cpp +39 -0
- esphome/components/uptime/uptime_timestamp_sensor.h +30 -0
- esphome/components/veml7700/veml7700.cpp +1 -1
- esphome/components/veml7700/veml7700.h +5 -5
- esphome/components/voice_assistant/voice_assistant.cpp +4 -2
- esphome/components/web_server/server_index_v2.h +42 -41
- esphome/components/web_server/server_index_v3.h +368 -367
- esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
- esphome/components/wifi/wifi_component_pico_w.cpp +18 -2
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/x9c/output.py +7 -1
- esphome/const.py +2 -1
- esphome/core/defines.h +1 -0
- esphome/core/helpers.cpp +2 -2
- esphome/core/helpers.h +1 -1
- esphome/external_files.py +26 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/METADATA +1 -1
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/RECORD +101 -95
- esphome/components/micro_wake_word/audio_preprocessor_int8_model_data.h +0 -493
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/LICENSE +0 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/WHEEL +0 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/top_level.txt +0 -0
@@ -93,8 +93,9 @@ void AHT10Component::restart_read_() {
|
|
93
93
|
|
94
94
|
void AHT10Component::read_data_() {
|
95
95
|
uint8_t data[6];
|
96
|
-
if (this->read_count_ > 1)
|
96
|
+
if (this->read_count_ > 1) {
|
97
97
|
ESP_LOGD(TAG, "Read attempt %d at %ums", this->read_count_, (unsigned) (millis() - this->start_time_));
|
98
|
+
}
|
98
99
|
if (this->read(data, 6) != i2c::ERROR_OK) {
|
99
100
|
this->status_set_warning("AHT10 read failed, retrying soon");
|
100
101
|
this->restart_read_();
|
@@ -119,8 +120,9 @@ void AHT10Component::read_data_() {
|
|
119
120
|
return;
|
120
121
|
}
|
121
122
|
}
|
122
|
-
if (this->read_count_ > 1)
|
123
|
+
if (this->read_count_ > 1) {
|
123
124
|
ESP_LOGD(TAG, "Success at %ums", (unsigned) (millis() - this->start_time_));
|
125
|
+
}
|
124
126
|
uint32_t raw_temperature = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5];
|
125
127
|
uint32_t raw_humidity = ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4;
|
126
128
|
|
@@ -574,21 +574,25 @@ void Climate::dump_traits_(const char *tag) {
|
|
574
574
|
ESP_LOGCONFIG(tag, " - Max temperature: %.1f", traits.get_visual_max_temperature());
|
575
575
|
ESP_LOGCONFIG(tag, " - Temperature step:");
|
576
576
|
ESP_LOGCONFIG(tag, " Target: %.1f", traits.get_visual_target_temperature_step());
|
577
|
-
ESP_LOGCONFIG(tag, " Current: %.1f", traits.get_visual_current_temperature_step());
|
578
|
-
ESP_LOGCONFIG(tag, " - Min humidity: %.0f", traits.get_visual_min_humidity());
|
579
|
-
ESP_LOGCONFIG(tag, " - Max humidity: %.0f", traits.get_visual_max_humidity());
|
580
577
|
if (traits.get_supports_current_temperature()) {
|
581
|
-
ESP_LOGCONFIG(tag, "
|
578
|
+
ESP_LOGCONFIG(tag, " Current: %.1f", traits.get_visual_current_temperature_step());
|
582
579
|
}
|
583
|
-
if (traits.get_supports_current_humidity()) {
|
584
|
-
ESP_LOGCONFIG(tag, "
|
580
|
+
if (traits.get_supports_target_humidity() || traits.get_supports_current_humidity()) {
|
581
|
+
ESP_LOGCONFIG(tag, " - Min humidity: %.0f", traits.get_visual_min_humidity());
|
582
|
+
ESP_LOGCONFIG(tag, " - Max humidity: %.0f", traits.get_visual_max_humidity());
|
585
583
|
}
|
586
584
|
if (traits.get_supports_two_point_target_temperature()) {
|
587
585
|
ESP_LOGCONFIG(tag, " [x] Supports two-point target temperature");
|
588
586
|
}
|
587
|
+
if (traits.get_supports_current_temperature()) {
|
588
|
+
ESP_LOGCONFIG(tag, " [x] Supports current temperature");
|
589
|
+
}
|
589
590
|
if (traits.get_supports_target_humidity()) {
|
590
591
|
ESP_LOGCONFIG(tag, " [x] Supports target humidity");
|
591
592
|
}
|
593
|
+
if (traits.get_supports_current_humidity()) {
|
594
|
+
ESP_LOGCONFIG(tag, " [x] Supports current humidity");
|
595
|
+
}
|
592
596
|
if (traits.get_supports_action()) {
|
593
597
|
ESP_LOGCONFIG(tag, " [x] Supports action");
|
594
598
|
}
|
@@ -73,7 +73,7 @@ class ClimateTraits {
|
|
73
73
|
ESPDEPRECATED("This method is deprecated, use set_supported_modes() instead", "v1.20")
|
74
74
|
void set_supports_dry_mode(bool supports_dry_mode) { set_mode_support_(CLIMATE_MODE_DRY, supports_dry_mode); }
|
75
75
|
bool supports_mode(ClimateMode mode) const { return supported_modes_.count(mode); }
|
76
|
-
std::set<ClimateMode> get_supported_modes() const { return supported_modes_; }
|
76
|
+
const std::set<ClimateMode> &get_supported_modes() const { return supported_modes_; }
|
77
77
|
|
78
78
|
void set_supports_action(bool supports_action) { supports_action_ = supports_action; }
|
79
79
|
bool get_supports_action() const { return supports_action_; }
|
@@ -101,7 +101,7 @@ class ClimateTraits {
|
|
101
101
|
void set_supports_fan_mode_diffuse(bool supported) { set_fan_mode_support_(CLIMATE_FAN_DIFFUSE, supported); }
|
102
102
|
bool supports_fan_mode(ClimateFanMode fan_mode) const { return supported_fan_modes_.count(fan_mode); }
|
103
103
|
bool get_supports_fan_modes() const { return !supported_fan_modes_.empty() || !supported_custom_fan_modes_.empty(); }
|
104
|
-
std::set<ClimateFanMode> get_supported_fan_modes() const { return supported_fan_modes_; }
|
104
|
+
const std::set<ClimateFanMode> &get_supported_fan_modes() const { return supported_fan_modes_; }
|
105
105
|
|
106
106
|
void set_supported_custom_fan_modes(std::set<std::string> supported_custom_fan_modes) {
|
107
107
|
supported_custom_fan_modes_ = std::move(supported_custom_fan_modes);
|
@@ -140,7 +140,7 @@ class ClimateTraits {
|
|
140
140
|
}
|
141
141
|
bool supports_swing_mode(ClimateSwingMode swing_mode) const { return supported_swing_modes_.count(swing_mode); }
|
142
142
|
bool get_supports_swing_modes() const { return !supported_swing_modes_.empty(); }
|
143
|
-
std::set<ClimateSwingMode> get_supported_swing_modes() const { return supported_swing_modes_; }
|
143
|
+
const std::set<ClimateSwingMode> &get_supported_swing_modes() const { return supported_swing_modes_; }
|
144
144
|
|
145
145
|
float get_visual_min_temperature() const { return visual_min_temperature_; }
|
146
146
|
void set_visual_min_temperature(float visual_min_temperature) { visual_min_temperature_ = visual_min_temperature; }
|
esphome/components/cover/cover.h
CHANGED
@@ -129,13 +129,13 @@ class Cover : public EntityBase, public EntityBase_DeviceClass {
|
|
129
129
|
*
|
130
130
|
* This is a legacy method and may be removed later, please use `.make_call()` instead.
|
131
131
|
*/
|
132
|
-
ESPDEPRECATED("open() is deprecated, use make_call().set_command_open() instead.", "2021.9")
|
132
|
+
ESPDEPRECATED("open() is deprecated, use make_call().set_command_open().perform() instead.", "2021.9")
|
133
133
|
void open();
|
134
134
|
/** Close the cover.
|
135
135
|
*
|
136
136
|
* This is a legacy method and may be removed later, please use `.make_call()` instead.
|
137
137
|
*/
|
138
|
-
ESPDEPRECATED("close() is deprecated, use make_call().set_command_close() instead.", "2021.9")
|
138
|
+
ESPDEPRECATED("close() is deprecated, use make_call().set_command_close().perform() instead.", "2021.9")
|
139
139
|
void close();
|
140
140
|
/** Stop the cover.
|
141
141
|
*
|
@@ -17,7 +17,7 @@ from esphome.const import (
|
|
17
17
|
CONF_VSYNC_PIN,
|
18
18
|
)
|
19
19
|
from esphome.core import CORE
|
20
|
-
from esphome.components.esp32 import
|
20
|
+
from esphome.components.esp32 import add_idf_component
|
21
21
|
from esphome.cpp_helpers import setup_entity
|
22
22
|
|
23
23
|
DEPENDENCIES = ["esp32"]
|
@@ -290,8 +290,11 @@ async def to_code(config):
|
|
290
290
|
cg.add_define("USE_ESP32_CAMERA")
|
291
291
|
|
292
292
|
if CORE.using_esp_idf:
|
293
|
-
|
294
|
-
|
293
|
+
add_idf_component(
|
294
|
+
name="esp32-camera",
|
295
|
+
repo="https://github.com/espressif/esp32-camera.git",
|
296
|
+
ref="v2.0.9",
|
297
|
+
)
|
295
298
|
|
296
299
|
for conf in config.get(CONF_ON_STREAM_START, []):
|
297
300
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
@@ -11,6 +11,7 @@ from esphome.components.esp32.const import (
|
|
11
11
|
VARIANT_ESP32S2,
|
12
12
|
VARIANT_ESP32S3,
|
13
13
|
VARIANT_ESP32C3,
|
14
|
+
VARIANT_ESP32C6,
|
14
15
|
VARIANT_ESP32H2,
|
15
16
|
)
|
16
17
|
|
@@ -47,6 +48,7 @@ CAN_SPEEDS_ESP32_S2 = {
|
|
47
48
|
|
48
49
|
CAN_SPEEDS_ESP32_S3 = {**CAN_SPEEDS_ESP32_S2}
|
49
50
|
CAN_SPEEDS_ESP32_C3 = {**CAN_SPEEDS_ESP32_S2}
|
51
|
+
CAN_SPEEDS_ESP32_C6 = {**CAN_SPEEDS_ESP32_S2}
|
50
52
|
CAN_SPEEDS_ESP32_H2 = {**CAN_SPEEDS_ESP32_S2}
|
51
53
|
|
52
54
|
CAN_SPEEDS = {
|
@@ -54,6 +56,7 @@ CAN_SPEEDS = {
|
|
54
56
|
VARIANT_ESP32S2: CAN_SPEEDS_ESP32_S2,
|
55
57
|
VARIANT_ESP32S3: CAN_SPEEDS_ESP32_S3,
|
56
58
|
VARIANT_ESP32C3: CAN_SPEEDS_ESP32_C3,
|
59
|
+
VARIANT_ESP32C6: CAN_SPEEDS_ESP32_C6,
|
57
60
|
VARIANT_ESP32H2: CAN_SPEEDS_ESP32_H2,
|
58
61
|
}
|
59
62
|
|
@@ -65,7 +65,8 @@ void EthernetComponent::setup() {
|
|
65
65
|
.intr_flags = 0,
|
66
66
|
};
|
67
67
|
|
68
|
-
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
68
|
+
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \
|
69
|
+
defined(USE_ESP32_VARIANT_ESP32C6)
|
69
70
|
auto host = SPI2_HOST;
|
70
71
|
#else
|
71
72
|
auto host = SPI3_HOST;
|
@@ -393,7 +394,7 @@ void EthernetComponent::got_ip_event_handler(void *arg, esp_event_base_t event_b
|
|
393
394
|
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
394
395
|
ESP_LOGV(TAG, "[Ethernet event] ETH Got IP " IPSTR, IP2STR(&ip_info->ip));
|
395
396
|
global_eth_component->got_ipv4_address_ = true;
|
396
|
-
#if USE_NETWORK_IPV6
|
397
|
+
#if USE_NETWORK_IPV6 && (USE_NETWORK_MIN_IPV6_ADDR_COUNT > 0)
|
397
398
|
global_eth_component->connected_ = global_eth_component->ipv6_count_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT;
|
398
399
|
#else
|
399
400
|
global_eth_component->connected_ = true;
|
@@ -406,8 +407,12 @@ void EthernetComponent::got_ip6_event_handler(void *arg, esp_event_base_t event_
|
|
406
407
|
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *) event_data;
|
407
408
|
ESP_LOGV(TAG, "[Ethernet event] ETH Got IPv6: " IPV6STR, IPV62STR(event->ip6_info.ip));
|
408
409
|
global_eth_component->ipv6_count_ += 1;
|
410
|
+
#if (USE_NETWORK_MIN_IPV6_ADDR_COUNT > 0)
|
409
411
|
global_eth_component->connected_ =
|
410
412
|
global_eth_component->got_ipv4_address_ && (global_eth_component->ipv6_count_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT);
|
413
|
+
#else
|
414
|
+
global_eth_component->connected_ = global_eth_component->got_ipv4_address_;
|
415
|
+
#endif
|
411
416
|
}
|
412
417
|
#endif /* USE_NETWORK_IPV6 */
|
413
418
|
|
@@ -631,7 +636,7 @@ void EthernetComponent::write_phy_register_(esp_eth_mac_t *mac, PHYRegister regi
|
|
631
636
|
ESPHL_ERROR_CHECK(err, "Writing PHY Register failed");
|
632
637
|
|
633
638
|
if (this->type_ == ETHERNET_TYPE_RTL8201 && register_data.page) {
|
634
|
-
ESP_LOGD(TAG, "Select PHY Register Page
|
639
|
+
ESP_LOGD(TAG, "Select PHY Register Page 0x00");
|
635
640
|
err = mac->write_phy_reg(mac, this->phy_addr_, eth_phy_psr_reg_addr, 0x0);
|
636
641
|
ESPHL_ERROR_CHECK(err, "Select PHY Register Page 0 failed");
|
637
642
|
}
|
@@ -17,7 +17,6 @@ from esphome.helpers import (
|
|
17
17
|
cpp_string_escape,
|
18
18
|
)
|
19
19
|
from esphome.const import (
|
20
|
-
__version__,
|
21
20
|
CONF_FAMILY,
|
22
21
|
CONF_FILE,
|
23
22
|
CONF_GLYPHS,
|
@@ -185,31 +184,6 @@ def get_font_path(value, type) -> Path:
|
|
185
184
|
return None
|
186
185
|
|
187
186
|
|
188
|
-
def download_content(url: str, path: Path) -> None:
|
189
|
-
if not external_files.has_remote_file_changed(url, path):
|
190
|
-
_LOGGER.debug("Remote file has not changed %s", url)
|
191
|
-
return
|
192
|
-
|
193
|
-
_LOGGER.debug(
|
194
|
-
"Remote file has changed, downloading from %s to %s",
|
195
|
-
url,
|
196
|
-
path,
|
197
|
-
)
|
198
|
-
|
199
|
-
try:
|
200
|
-
req = requests.get(
|
201
|
-
url,
|
202
|
-
timeout=external_files.NETWORK_TIMEOUT,
|
203
|
-
headers={"User-agent": f"ESPHome/{__version__} (https://esphome.io)"},
|
204
|
-
)
|
205
|
-
req.raise_for_status()
|
206
|
-
except requests.exceptions.RequestException as e:
|
207
|
-
raise cv.Invalid(f"Could not download from {url}: {e}")
|
208
|
-
|
209
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
210
|
-
path.write_bytes(req.content)
|
211
|
-
|
212
|
-
|
213
187
|
def download_gfont(value):
|
214
188
|
name = (
|
215
189
|
f"{value[CONF_FAMILY]}:ital,wght@{int(value[CONF_ITALIC])},{value[CONF_WEIGHT]}"
|
@@ -236,7 +210,7 @@ def download_gfont(value):
|
|
236
210
|
ttf_url = match.group(1)
|
237
211
|
_LOGGER.debug("download_gfont: ttf_url=%s", ttf_url)
|
238
212
|
|
239
|
-
download_content(ttf_url, path)
|
213
|
+
external_files.download_content(ttf_url, path)
|
240
214
|
return value
|
241
215
|
|
242
216
|
|
@@ -244,7 +218,7 @@ def download_web_font(value):
|
|
244
218
|
url = value[CONF_URL]
|
245
219
|
path = get_font_path(value, TYPE_WEB)
|
246
220
|
|
247
|
-
download_content(url, path)
|
221
|
+
external_files.download_content(url, path)
|
248
222
|
_LOGGER.debug("download_web_font: path=%s", path)
|
249
223
|
return value
|
250
224
|
|
esphome/components/gree/gree.cpp
CHANGED
@@ -24,7 +24,7 @@ void GreeClimate::transmit_state() {
|
|
24
24
|
remote_state[4] |= (this->horizontal_swing_() << 4);
|
25
25
|
}
|
26
26
|
|
27
|
-
if (this->model_ == GREE_YAA || this->model_ == GREE_YAC) {
|
27
|
+
if (this->model_ == GREE_YAA || this->model_ == GREE_YAC || this->model_ == GREE_YAC1FB9) {
|
28
28
|
remote_state[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO,LIGHT,HEALTH,X-FAN
|
29
29
|
remote_state[3] = 0x50; // bits 4..7 always 0101
|
30
30
|
remote_state[6] = 0x20; // YAA1FB, FAA1FB1, YB1F2 bits 4..7 always 0010
|
@@ -53,7 +53,11 @@ void GreeClimate::transmit_state() {
|
|
53
53
|
data->set_carrier_frequency(GREE_IR_FREQUENCY);
|
54
54
|
|
55
55
|
data->mark(GREE_HEADER_MARK);
|
56
|
-
|
56
|
+
if (this->model_ == GREE_YAC1FB9) {
|
57
|
+
data->space(GREE_YAC1FB9_HEADER_SPACE);
|
58
|
+
} else {
|
59
|
+
data->space(GREE_HEADER_SPACE);
|
60
|
+
}
|
57
61
|
|
58
62
|
for (int i = 0; i < 4; i++) {
|
59
63
|
for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
|
@@ -71,7 +75,11 @@ void GreeClimate::transmit_state() {
|
|
71
75
|
data->space(GREE_ZERO_SPACE);
|
72
76
|
|
73
77
|
data->mark(GREE_BIT_MARK);
|
74
|
-
|
78
|
+
if (this->model_ == GREE_YAC1FB9) {
|
79
|
+
data->space(GREE_YAC1FB9_MESSAGE_SPACE);
|
80
|
+
} else {
|
81
|
+
data->space(GREE_MESSAGE_SPACE);
|
82
|
+
}
|
75
83
|
|
76
84
|
for (int i = 4; i < 8; i++) {
|
77
85
|
for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
|
esphome/components/gree/gree.h
CHANGED
@@ -41,6 +41,10 @@ const uint32_t GREE_YAC_HEADER_MARK = 6000;
|
|
41
41
|
const uint32_t GREE_YAC_HEADER_SPACE = 3000;
|
42
42
|
const uint32_t GREE_YAC_BIT_MARK = 650;
|
43
43
|
|
44
|
+
// Timing specific to YAC1FB9
|
45
|
+
const uint32_t GREE_YAC1FB9_HEADER_SPACE = 4500;
|
46
|
+
const uint32_t GREE_YAC1FB9_MESSAGE_SPACE = 19980;
|
47
|
+
|
44
48
|
// State Frame size
|
45
49
|
const uint8_t GREE_STATE_FRAME_SIZE = 8;
|
46
50
|
|
@@ -67,7 +71,7 @@ const uint8_t GREE_HDIR_MRIGHT = 0x05;
|
|
67
71
|
const uint8_t GREE_HDIR_RIGHT = 0x06;
|
68
72
|
|
69
73
|
// Model codes
|
70
|
-
enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC };
|
74
|
+
enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC, GREE_YAC1FB9 };
|
71
75
|
|
72
76
|
class GreeClimate : public climate_ir::ClimateIR {
|
73
77
|
public:
|
@@ -56,7 +56,7 @@ SENSOR_TYPES = {
|
|
56
56
|
|
57
57
|
CONFIG_SCHEMA = cv.Schema(
|
58
58
|
{
|
59
|
-
cv.
|
59
|
+
cv.GenerateID(CONF_HAIER_ID): cv.use_id(HonClimate),
|
60
60
|
}
|
61
61
|
).extend({cv.Optional(type): schema for type, schema in SENSOR_TYPES.items()})
|
62
62
|
|
@@ -64,8 +64,8 @@ CONFIG_SCHEMA = cv.Schema(
|
|
64
64
|
async def to_code(config):
|
65
65
|
paren = await cg.get_variable(config[CONF_HAIER_ID])
|
66
66
|
|
67
|
-
for
|
68
|
-
if conf := config.get(
|
67
|
+
for type_ in SENSOR_TYPES:
|
68
|
+
if conf := config.get(type_):
|
69
69
|
sens = await binary_sensor.new_binary_sensor(conf)
|
70
|
-
binary_sensor_type = getattr(BinarySensorTypeEnum,
|
70
|
+
binary_sensor_type = getattr(BinarySensorTypeEnum, type_.upper())
|
71
71
|
cg.add(paren.set_sub_binary_sensor(binary_sensor_type, sens))
|
@@ -21,7 +21,7 @@ ICON_SPRAY_BOTTLE = "mdi:spray-bottle"
|
|
21
21
|
|
22
22
|
CONFIG_SCHEMA = cv.Schema(
|
23
23
|
{
|
24
|
-
cv.
|
24
|
+
cv.GenerateID(CONF_HAIER_ID): cv.use_id(HonClimate),
|
25
25
|
cv.Optional(CONF_SELF_CLEANING): button.button_schema(
|
26
26
|
SelfCleaningButton,
|
27
27
|
icon=ICON_SPRAY_BOTTLE,
|
@@ -38,6 +38,9 @@ PROTOCOL_MAX_TEMPERATURE = 30.0
|
|
38
38
|
PROTOCOL_TARGET_TEMPERATURE_STEP = 1.0
|
39
39
|
PROTOCOL_CURRENT_TEMPERATURE_STEP = 0.5
|
40
40
|
PROTOCOL_CONTROL_PACKET_SIZE = 10
|
41
|
+
PROTOCOL_MIN_SENSORS_PACKET_SIZE = 18
|
42
|
+
PROTOCOL_DEFAULT_SENSORS_PACKET_SIZE = 22
|
43
|
+
PROTOCOL_STATUS_MESSAGE_HEADER_SIZE = 0
|
41
44
|
|
42
45
|
CODEOWNERS = ["@paveldn"]
|
43
46
|
DEPENDENCIES = ["climate", "uart"]
|
@@ -48,6 +51,9 @@ CONF_CONTROL_PACKET_SIZE = "control_packet_size"
|
|
48
51
|
CONF_HORIZONTAL_AIRFLOW = "horizontal_airflow"
|
49
52
|
CONF_ON_ALARM_START = "on_alarm_start"
|
50
53
|
CONF_ON_ALARM_END = "on_alarm_end"
|
54
|
+
CONF_ON_STATUS_MESSAGE = "on_status_message"
|
55
|
+
CONF_SENSORS_PACKET_SIZE = "sensors_packet_size"
|
56
|
+
CONF_STATUS_MESSAGE_HEADER_SIZE = "status_message_header_size"
|
51
57
|
CONF_VERTICAL_AIRFLOW = "vertical_airflow"
|
52
58
|
CONF_WIFI_SIGNAL = "wifi_signal"
|
53
59
|
|
@@ -129,6 +135,11 @@ HaierAlarmEndTrigger = haier_ns.class_(
|
|
129
135
|
automation.Trigger.template(cg.uint8, cg.const_char_ptr),
|
130
136
|
)
|
131
137
|
|
138
|
+
StatusMessageTrigger = haier_ns.class_(
|
139
|
+
"StatusMessageTrigger",
|
140
|
+
automation.Trigger.template(cg.const_char_ptr, cg.size_t),
|
141
|
+
)
|
142
|
+
|
132
143
|
|
133
144
|
def validate_visual(config):
|
134
145
|
if CONF_VISUAL in config:
|
@@ -183,7 +194,6 @@ BASE_CONFIG_SCHEMA = (
|
|
183
194
|
cv.Optional(
|
184
195
|
CONF_SUPPORTED_SWING_MODES,
|
185
196
|
default=[
|
186
|
-
"OFF",
|
187
197
|
"VERTICAL",
|
188
198
|
"HORIZONTAL",
|
189
199
|
"BOTH",
|
@@ -194,6 +204,11 @@ BASE_CONFIG_SCHEMA = (
|
|
194
204
|
cv.Optional(
|
195
205
|
CONF_ANSWER_TIMEOUT,
|
196
206
|
): cv.positive_time_period_milliseconds,
|
207
|
+
cv.Optional(CONF_ON_STATUS_MESSAGE): automation.validate_automation(
|
208
|
+
{
|
209
|
+
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StatusMessageTrigger),
|
210
|
+
}
|
211
|
+
),
|
197
212
|
}
|
198
213
|
)
|
199
214
|
.extend(uart.UART_DEVICE_SCHEMA)
|
@@ -211,7 +226,7 @@ CONFIG_SCHEMA = cv.All(
|
|
211
226
|
): cv.boolean,
|
212
227
|
cv.Optional(
|
213
228
|
CONF_SUPPORTED_PRESETS,
|
214
|
-
default=
|
229
|
+
default=["BOOST", "COMFORT"], # No AWAY by default
|
215
230
|
): cv.ensure_list(
|
216
231
|
cv.enum(SUPPORTED_CLIMATE_PRESETS_SMARTAIR2_OPTIONS, upper=True)
|
217
232
|
),
|
@@ -229,9 +244,17 @@ CONFIG_SCHEMA = cv.All(
|
|
229
244
|
cv.Optional(
|
230
245
|
CONF_CONTROL_PACKET_SIZE, default=PROTOCOL_CONTROL_PACKET_SIZE
|
231
246
|
): cv.int_range(min=PROTOCOL_CONTROL_PACKET_SIZE, max=50),
|
247
|
+
cv.Optional(
|
248
|
+
CONF_SENSORS_PACKET_SIZE,
|
249
|
+
default=PROTOCOL_DEFAULT_SENSORS_PACKET_SIZE,
|
250
|
+
): cv.int_range(min=PROTOCOL_MIN_SENSORS_PACKET_SIZE, max=50),
|
251
|
+
cv.Optional(
|
252
|
+
CONF_STATUS_MESSAGE_HEADER_SIZE,
|
253
|
+
default=PROTOCOL_STATUS_MESSAGE_HEADER_SIZE,
|
254
|
+
): cv.int_range(min=PROTOCOL_STATUS_MESSAGE_HEADER_SIZE),
|
232
255
|
cv.Optional(
|
233
256
|
CONF_SUPPORTED_PRESETS,
|
234
|
-
default=
|
257
|
+
default=["BOOST", "ECO", "SLEEP"], # No AWAY by default
|
235
258
|
): cv.ensure_list(
|
236
259
|
cv.enum(SUPPORTED_CLIMATE_PRESETS_HON_OPTIONS, upper=True)
|
237
260
|
),
|
@@ -427,11 +450,7 @@ def _final_validate(config):
|
|
427
450
|
"No logger component found, logging for Haier protocol is disabled"
|
428
451
|
)
|
429
452
|
cg.add_build_flag("-DHAIER_LOG_LEVEL=0")
|
430
|
-
if (
|
431
|
-
(CONF_WIFI_SIGNAL in config)
|
432
|
-
and (config[CONF_WIFI_SIGNAL])
|
433
|
-
and CONF_WIFI not in full_config
|
434
|
-
):
|
453
|
+
if config.get(CONF_WIFI_SIGNAL) and CONF_WIFI not in full_config:
|
435
454
|
raise cv.Invalid(
|
436
455
|
f"No WiFi configured, if you want to use haier climate without WiFi add {CONF_WIFI_SIGNAL}: false to climate configuration"
|
437
456
|
)
|
@@ -473,6 +492,16 @@ async def to_code(config):
|
|
473
492
|
config[CONF_CONTROL_PACKET_SIZE] - PROTOCOL_CONTROL_PACKET_SIZE
|
474
493
|
)
|
475
494
|
)
|
495
|
+
if CONF_SENSORS_PACKET_SIZE in config:
|
496
|
+
cg.add(
|
497
|
+
var.set_extra_sensors_packet_bytes_size(
|
498
|
+
config[CONF_SENSORS_PACKET_SIZE] - PROTOCOL_MIN_SENSORS_PACKET_SIZE
|
499
|
+
)
|
500
|
+
)
|
501
|
+
if CONF_STATUS_MESSAGE_HEADER_SIZE in config:
|
502
|
+
cg.add(
|
503
|
+
var.set_status_message_header_size(config[CONF_STATUS_MESSAGE_HEADER_SIZE])
|
504
|
+
)
|
476
505
|
for conf in config.get(CONF_ON_ALARM_START, []):
|
477
506
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
478
507
|
await automation.build_automation(
|
@@ -483,5 +512,10 @@ async def to_code(config):
|
|
483
512
|
await automation.build_automation(
|
484
513
|
trigger, [(cg.uint8, "code"), (cg.const_char_ptr, "message")], conf
|
485
514
|
)
|
515
|
+
for conf in config.get(CONF_ON_STATUS_MESSAGE, []):
|
516
|
+
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
517
|
+
await automation.build_automation(
|
518
|
+
trigger, [(cg.const_char_ptr, "data"), (cg.size_t, "data_size")], conf
|
519
|
+
)
|
486
520
|
# https://github.com/paveldn/HaierProtocol
|
487
|
-
cg.add_library("pavlodn/HaierProtocol", "0.9.
|
521
|
+
cg.add_library("pavlodn/HaierProtocol", "0.9.31")
|
@@ -186,6 +186,10 @@ void HaierClimateBase::send_custom_command(const haier_protocol::HaierMessage &m
|
|
186
186
|
this->action_request_ = PendingAction({ActionRequest::SEND_CUSTOM_COMMAND, message});
|
187
187
|
}
|
188
188
|
|
189
|
+
void HaierClimateBase::add_status_message_callback(std::function<void(const char *, size_t)> &&callback) {
|
190
|
+
this->status_message_callback_.add(std::move(callback));
|
191
|
+
}
|
192
|
+
|
189
193
|
haier_protocol::HandlerError HaierClimateBase::answer_preprocess_(
|
190
194
|
haier_protocol::FrameType request_message_type, haier_protocol::FrameType expected_request_message_type,
|
191
195
|
haier_protocol::FrameType answer_message_type, haier_protocol::FrameType expected_answer_message_type,
|
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <set>
|
5
5
|
#include "esphome/components/climate/climate.h"
|
6
6
|
#include "esphome/components/uart/uart.h"
|
7
|
+
#include "esphome/core/automation.h"
|
7
8
|
// HaierProtocol
|
8
9
|
#include <protocol/haier_protocol.h>
|
9
10
|
|
@@ -56,6 +57,7 @@ class HaierClimateBase : public esphome::Component,
|
|
56
57
|
void set_answer_timeout(uint32_t timeout);
|
57
58
|
void set_send_wifi(bool send_wifi);
|
58
59
|
void send_custom_command(const haier_protocol::HaierMessage &message);
|
60
|
+
void add_status_message_callback(std::function<void(const char *, size_t)> &&callback);
|
59
61
|
|
60
62
|
protected:
|
61
63
|
enum class ProtocolPhases {
|
@@ -140,11 +142,19 @@ class HaierClimateBase : public esphome::Component,
|
|
140
142
|
esphome::climate::ClimateTraits traits_;
|
141
143
|
HvacSettings current_hvac_settings_;
|
142
144
|
HvacSettings next_hvac_settings_;
|
143
|
-
std::unique_ptr<uint8_t[]> last_status_message_;
|
145
|
+
std::unique_ptr<uint8_t[]> last_status_message_{nullptr};
|
144
146
|
std::chrono::steady_clock::time_point last_request_timestamp_; // For interval between messages
|
145
147
|
std::chrono::steady_clock::time_point last_valid_status_timestamp_; // For protocol timeout
|
146
148
|
std::chrono::steady_clock::time_point last_status_request_; // To request AC status
|
147
149
|
std::chrono::steady_clock::time_point last_signal_request_; // To send WiFI signal level
|
150
|
+
CallbackManager<void(const char *, size_t)> status_message_callback_{};
|
151
|
+
};
|
152
|
+
|
153
|
+
class StatusMessageTrigger : public Trigger<const char *, size_t> {
|
154
|
+
public:
|
155
|
+
explicit StatusMessageTrigger(HaierClimateBase *parent) {
|
156
|
+
parent->add_status_message_callback([this](const char *data, size_t data_size) { this->trigger(data, data_size); });
|
157
|
+
}
|
148
158
|
};
|
149
159
|
|
150
160
|
} // namespace haier
|