esphome 2024.6.6__py3-none-any.whl → 2024.7.0b1__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.
Files changed (78) hide show
  1. esphome/components/cover/cover.h +2 -2
  2. esphome/components/esp32_camera/__init__.py +6 -3
  3. esphome/components/ethernet/ethernet_component.cpp +3 -2
  4. esphome/components/font/__init__.py +2 -28
  5. esphome/components/haier/binary_sensor/__init__.py +4 -4
  6. esphome/components/haier/button/__init__.py +1 -1
  7. esphome/components/haier/climate.py +43 -9
  8. esphome/components/haier/haier_base.cpp +4 -0
  9. esphome/components/haier/haier_base.h +11 -1
  10. esphome/components/haier/hon_climate.cpp +109 -55
  11. esphome/components/haier/hon_climate.h +7 -1
  12. esphome/components/haier/hon_packet.h +5 -0
  13. esphome/components/haier/sensor/__init__.py +5 -5
  14. esphome/components/haier/smartair2_climate.cpp +1 -0
  15. esphome/components/haier/text_sensor/__init__.py +4 -4
  16. esphome/components/heatpumpir/climate.py +8 -2
  17. esphome/components/heatpumpir/heatpumpir.cpp +6 -0
  18. esphome/components/heatpumpir/heatpumpir.h +6 -0
  19. esphome/components/http_request/update/http_request_update.cpp +6 -7
  20. esphome/components/http_request/update/http_request_update.h +0 -3
  21. esphome/components/image/__init__.py +2 -29
  22. esphome/components/improv_serial/improv_serial_component.cpp +8 -8
  23. esphome/components/mdns/__init__.py +3 -3
  24. esphome/components/mdns/mdns_component.cpp +3 -1
  25. esphome/components/mdns/mdns_component.h +3 -1
  26. esphome/components/mdns/mdns_esp32.cpp +2 -1
  27. esphome/components/mdns/mdns_esp8266.cpp +2 -1
  28. esphome/components/mdns/mdns_host.cpp +2 -1
  29. esphome/components/mdns/mdns_libretiny.cpp +2 -1
  30. esphome/components/mdns/mdns_rp2040.cpp +2 -1
  31. esphome/components/micro_wake_word/__init__.py +203 -56
  32. esphome/components/micro_wake_word/micro_wake_word.cpp +225 -275
  33. esphome/components/micro_wake_word/micro_wake_word.h +77 -107
  34. esphome/components/micro_wake_word/preprocessor_settings.h +20 -0
  35. esphome/components/micro_wake_word/streaming_model.cpp +189 -0
  36. esphome/components/micro_wake_word/streaming_model.h +84 -0
  37. esphome/components/modbus_controller/text_sensor/__init__.py +2 -1
  38. esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +4 -1
  39. esphome/components/modbus_controller/text_sensor/modbus_textsensor.h +1 -1
  40. esphome/components/number/__init__.py +2 -0
  41. esphome/components/qspi_amoled/display.py +16 -4
  42. esphome/components/qspi_amoled/qspi_amoled.cpp +16 -0
  43. esphome/components/qspi_amoled/qspi_amoled.h +0 -3
  44. esphome/components/remote_base/dooya_protocol.cpp +4 -4
  45. esphome/components/remote_base/rc_switch_protocol.cpp +1 -1
  46. esphome/components/script/__init__.py +1 -1
  47. esphome/components/sensor/__init__.py +2 -0
  48. esphome/components/tuya/tuya.cpp +8 -2
  49. esphome/components/tuya/tuya.h +3 -1
  50. esphome/components/uart/__init__.py +72 -9
  51. esphome/components/uart/uart_component_esp32_arduino.cpp +18 -4
  52. esphome/components/uart/uart_component_esp_idf.cpp +22 -2
  53. esphome/components/uart/uart_component_host.cpp +295 -0
  54. esphome/components/uart/uart_component_host.h +38 -0
  55. esphome/components/uptime/sensor.py +44 -11
  56. esphome/components/uptime/{uptime_sensor.cpp → uptime_seconds_sensor.cpp} +11 -7
  57. esphome/components/uptime/{uptime_sensor.h → uptime_seconds_sensor.h} +2 -2
  58. esphome/components/uptime/uptime_timestamp_sensor.cpp +39 -0
  59. esphome/components/uptime/uptime_timestamp_sensor.h +30 -0
  60. esphome/components/veml7700/veml7700.cpp +1 -1
  61. esphome/components/veml7700/veml7700.h +5 -5
  62. esphome/components/voice_assistant/voice_assistant.cpp +1 -1
  63. esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
  64. esphome/components/wifi/wifi_component_pico_w.cpp +18 -2
  65. esphome/components/wireguard/__init__.py +1 -1
  66. esphome/components/x9c/output.py +7 -1
  67. esphome/const.py +2 -1
  68. esphome/core/defines.h +1 -0
  69. esphome/core/helpers.cpp +1 -1
  70. esphome/core/helpers.h +1 -1
  71. esphome/external_files.py +26 -0
  72. {esphome-2024.6.6.dist-info → esphome-2024.7.0b1.dist-info}/METADATA +1 -1
  73. {esphome-2024.6.6.dist-info → esphome-2024.7.0b1.dist-info}/RECORD +77 -71
  74. esphome/components/micro_wake_word/audio_preprocessor_int8_model_data.h +0 -493
  75. {esphome-2024.6.6.dist-info → esphome-2024.7.0b1.dist-info}/LICENSE +0 -0
  76. {esphome-2024.6.6.dist-info → esphome-2024.7.0b1.dist-info}/WHEEL +0 -0
  77. {esphome-2024.6.6.dist-info → esphome-2024.7.0b1.dist-info}/entry_points.txt +0 -0
  78. {esphome-2024.6.6.dist-info → esphome-2024.7.0b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,38 @@
1
+ #pragma once
2
+
3
+ #ifdef USE_HOST
4
+
5
+ #include "esphome/core/component.h"
6
+ #include "esphome/core/log.h"
7
+ #include "uart_component.h"
8
+
9
+ namespace esphome {
10
+ namespace uart {
11
+
12
+ class HostUartComponent : public UARTComponent, public Component {
13
+ public:
14
+ virtual ~HostUartComponent();
15
+ void setup() override;
16
+ void dump_config() override;
17
+ float get_setup_priority() const override { return setup_priority::BUS; }
18
+ void write_array(const uint8_t *data, size_t len) override;
19
+ bool peek_byte(uint8_t *data) override;
20
+ bool read_array(uint8_t *data, size_t len) override;
21
+ int available() override;
22
+ void flush() override;
23
+ void set_name(std::string port_name) { port_name_ = port_name; };
24
+
25
+ protected:
26
+ void update_error_(const std::string &error);
27
+ void check_logger_conflict() override {}
28
+ std::string port_name_;
29
+ std::string first_error_{""};
30
+ int file_descriptor_ = -1;
31
+ bool has_peek_{false};
32
+ uint8_t peek_byte_;
33
+ };
34
+
35
+ } // namespace uart
36
+ } // namespace esphome
37
+
38
+ #endif // USE_HOST
@@ -1,7 +1,9 @@
1
1
  import esphome.codegen as cg
2
2
  import esphome.config_validation as cv
3
- from esphome.components import sensor
3
+ from esphome.components import sensor, time
4
4
  from esphome.const import (
5
+ CONF_TIME_ID,
6
+ DEVICE_CLASS_TIMESTAMP,
5
7
  ENTITY_CATEGORY_DIAGNOSTIC,
6
8
  STATE_CLASS_TOTAL_INCREASING,
7
9
  UNIT_SECOND,
@@ -10,19 +12,50 @@ from esphome.const import (
10
12
  )
11
13
 
12
14
  uptime_ns = cg.esphome_ns.namespace("uptime")
13
- UptimeSensor = uptime_ns.class_("UptimeSensor", sensor.Sensor, cg.PollingComponent)
15
+ UptimeSecondsSensor = uptime_ns.class_(
16
+ "UptimeSecondsSensor", sensor.Sensor, cg.PollingComponent
17
+ )
18
+ UptimeTimestampSensor = uptime_ns.class_(
19
+ "UptimeTimestampSensor", sensor.Sensor, cg.Component
20
+ )
14
21
 
15
- CONFIG_SCHEMA = sensor.sensor_schema(
16
- UptimeSensor,
17
- unit_of_measurement=UNIT_SECOND,
18
- icon=ICON_TIMER,
19
- accuracy_decimals=0,
20
- state_class=STATE_CLASS_TOTAL_INCREASING,
21
- device_class=DEVICE_CLASS_DURATION,
22
- entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
23
- ).extend(cv.polling_component_schema("60s"))
22
+
23
+ CONFIG_SCHEMA = cv.typed_schema(
24
+ {
25
+ "seconds": sensor.sensor_schema(
26
+ UptimeSecondsSensor,
27
+ unit_of_measurement=UNIT_SECOND,
28
+ icon=ICON_TIMER,
29
+ accuracy_decimals=0,
30
+ state_class=STATE_CLASS_TOTAL_INCREASING,
31
+ device_class=DEVICE_CLASS_DURATION,
32
+ entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
33
+ ).extend(cv.polling_component_schema("60s")),
34
+ "timestamp": sensor.sensor_schema(
35
+ UptimeTimestampSensor,
36
+ icon=ICON_TIMER,
37
+ accuracy_decimals=0,
38
+ device_class=DEVICE_CLASS_TIMESTAMP,
39
+ entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
40
+ )
41
+ .extend(
42
+ cv.Schema(
43
+ {
44
+ cv.GenerateID(CONF_TIME_ID): cv.All(
45
+ cv.requires_component("time"), cv.use_id(time.RealTimeClock)
46
+ ),
47
+ }
48
+ )
49
+ )
50
+ .extend(cv.COMPONENT_SCHEMA),
51
+ },
52
+ default_type="seconds",
53
+ )
24
54
 
25
55
 
26
56
  async def to_code(config):
27
57
  var = await sensor.new_sensor(config)
28
58
  await cg.register_component(var, config)
59
+ if time_id_config := config.get(CONF_TIME_ID):
60
+ time_id = await cg.get_variable(time_id_config)
61
+ cg.add(var.set_time(time_id))
@@ -1,14 +1,15 @@
1
- #include "uptime_sensor.h"
2
- #include "esphome/core/log.h"
3
- #include "esphome/core/helpers.h"
1
+ #include "uptime_seconds_sensor.h"
2
+
4
3
  #include "esphome/core/hal.h"
4
+ #include "esphome/core/helpers.h"
5
+ #include "esphome/core/log.h"
5
6
 
6
7
  namespace esphome {
7
8
  namespace uptime {
8
9
 
9
10
  static const char *const TAG = "uptime.sensor";
10
11
 
11
- void UptimeSensor::update() {
12
+ void UptimeSecondsSensor::update() {
12
13
  const uint32_t ms = millis();
13
14
  const uint64_t ms_mask = (1ULL << 32) - 1ULL;
14
15
  const uint32_t last_ms = this->uptime_ & ms_mask;
@@ -26,9 +27,12 @@ void UptimeSensor::update() {
26
27
  const float seconds = float(seconds_int) + (this->uptime_ % 1000ULL) / 1000.0f;
27
28
  this->publish_state(seconds);
28
29
  }
29
- std::string UptimeSensor::unique_id() { return get_mac_address() + "-uptime"; }
30
- float UptimeSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
31
- void UptimeSensor::dump_config() { LOG_SENSOR("", "Uptime Sensor", this); }
30
+ std::string UptimeSecondsSensor::unique_id() { return get_mac_address() + "-uptime"; }
31
+ float UptimeSecondsSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
32
+ void UptimeSecondsSensor::dump_config() {
33
+ LOG_SENSOR("", "Uptime Sensor", this);
34
+ ESP_LOGCONFIG(TAG, " Type: Seconds");
35
+ }
32
36
 
33
37
  } // namespace uptime
34
38
  } // namespace esphome
@@ -1,12 +1,12 @@
1
1
  #pragma once
2
2
 
3
- #include "esphome/core/component.h"
4
3
  #include "esphome/components/sensor/sensor.h"
4
+ #include "esphome/core/component.h"
5
5
 
6
6
  namespace esphome {
7
7
  namespace uptime {
8
8
 
9
- class UptimeSensor : public sensor::Sensor, public PollingComponent {
9
+ class UptimeSecondsSensor : public sensor::Sensor, public PollingComponent {
10
10
  public:
11
11
  void update() override;
12
12
  void dump_config() override;
@@ -0,0 +1,39 @@
1
+ #include "uptime_timestamp_sensor.h"
2
+
3
+ #ifdef USE_TIME
4
+
5
+ #include "esphome/core/hal.h"
6
+ #include "esphome/core/helpers.h"
7
+ #include "esphome/core/log.h"
8
+
9
+ namespace esphome {
10
+ namespace uptime {
11
+
12
+ static const char *const TAG = "uptime.sensor";
13
+
14
+ void UptimeTimestampSensor::setup() {
15
+ this->time_->add_on_time_sync_callback([this]() {
16
+ if (this->has_state_)
17
+ return; // No need to update the timestamp if it's already set
18
+
19
+ auto now = this->time_->now();
20
+ const uint32_t ms = millis();
21
+ if (!now.is_valid())
22
+ return; // No need to update the timestamp if the time is not valid
23
+
24
+ time_t timestamp = now.timestamp;
25
+ uint32_t seconds = ms / 1000;
26
+ timestamp -= seconds;
27
+ this->publish_state(timestamp);
28
+ });
29
+ }
30
+ float UptimeTimestampSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
31
+ void UptimeTimestampSensor::dump_config() {
32
+ LOG_SENSOR("", "Uptime Sensor", this);
33
+ ESP_LOGCONFIG(TAG, " Type: Timestamp");
34
+ }
35
+
36
+ } // namespace uptime
37
+ } // namespace esphome
38
+
39
+ #endif // USE_TIME
@@ -0,0 +1,30 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/defines.h"
4
+
5
+ #ifdef USE_TIME
6
+
7
+ #include "esphome/components/sensor/sensor.h"
8
+ #include "esphome/components/time/real_time_clock.h"
9
+ #include "esphome/core/component.h"
10
+
11
+ namespace esphome {
12
+ namespace uptime {
13
+
14
+ class UptimeTimestampSensor : public sensor::Sensor, public Component {
15
+ public:
16
+ void setup() override;
17
+ void dump_config() override;
18
+
19
+ float get_setup_priority() const override;
20
+
21
+ void set_time(time::RealTimeClock *time) { this->time_ = time; }
22
+
23
+ protected:
24
+ time::RealTimeClock *time_;
25
+ };
26
+
27
+ } // namespace uptime
28
+ } // namespace esphome
29
+
30
+ #endif // USE_TIME
@@ -243,7 +243,7 @@ ErrorCode VEML7700Component::configure_() {
243
243
  }
244
244
 
245
245
  PSMRegister psm{0};
246
- psm.PSM = PSM::PSM_MODE_1;
246
+ psm.PSM = PSMMode::PSM_MODE_1;
247
247
  psm.PSM_EN = false;
248
248
  ESP_LOGV(TAG, "Setting PSM to 0x%04X", psm.raw);
249
249
  err = this->write_register((uint8_t) CommandRegisters::PWR_SAVING, psm.raw_bytes, VEML_REG_SIZE);
@@ -24,7 +24,7 @@ enum class CommandRegisters : uint8_t {
24
24
  ALS_INT = 0x06 // R: ALS INT trigger event
25
25
  };
26
26
 
27
- enum Gain : uint8_t {
27
+ enum Gain : uint16_t {
28
28
  X_1 = 0,
29
29
  X_2 = 1,
30
30
  X_1_8 = 2,
@@ -32,7 +32,7 @@ enum Gain : uint8_t {
32
32
  };
33
33
  const uint8_t GAINS_COUNT = 4;
34
34
 
35
- enum IntegrationTime : uint8_t {
35
+ enum IntegrationTime : uint16_t {
36
36
  INTEGRATION_TIME_25MS = 0b1100,
37
37
  INTEGRATION_TIME_50MS = 0b1000,
38
38
  INTEGRATION_TIME_100MS = 0b0000,
@@ -42,14 +42,14 @@ enum IntegrationTime : uint8_t {
42
42
  };
43
43
  const uint8_t INTEGRATION_TIMES_COUNT = 6;
44
44
 
45
- enum Persistence : uint8_t {
45
+ enum Persistence : uint16_t {
46
46
  PERSISTENCE_1 = 0,
47
47
  PERSISTENCE_2 = 1,
48
48
  PERSISTENCE_4 = 2,
49
49
  PERSISTENCE_8 = 3,
50
50
  };
51
51
 
52
- enum PSM : uint8_t {
52
+ enum PSMMode : uint16_t {
53
53
  PSM_MODE_1 = 0,
54
54
  PSM_MODE_2 = 1,
55
55
  PSM_MODE_3 = 2,
@@ -92,7 +92,7 @@ union PSMRegister {
92
92
  uint8_t raw_bytes[2];
93
93
  struct {
94
94
  bool PSM_EN : 1;
95
- uint8_t PSM : 2;
95
+ PSMMode PSM : 2;
96
96
  uint16_t reserved : 13;
97
97
  } __attribute__((packed));
98
98
  };
@@ -799,7 +799,7 @@ void VoiceAssistant::on_audio(const api::VoiceAssistantAudio &msg) {
799
799
  this->speaker_buffer_index_ += msg.data.length();
800
800
  this->speaker_buffer_size_ += msg.data.length();
801
801
  this->speaker_bytes_received_ += msg.data.length();
802
- ESP_LOGV(TAG, "Received audio: %" PRId32 " bytes from API", msg.data.length());
802
+ ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data.length());
803
803
  } else {
804
804
  ESP_LOGE(TAG, "Cannot receive audio, buffer is full");
805
805
  }
@@ -757,7 +757,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
757
757
 
758
758
  WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() {
759
759
  if (s_sta_connected && this->got_ipv4_address_) {
760
- #if USE_NETWORK_IPV6
760
+ #if USE_NETWORK_IPV6 && (USE_NETWORK_MIN_IPV6_ADDR_COUNT > 0)
761
761
  if (this->num_ipv6_addresses_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT) {
762
762
  return WiFiSTAConnectStatus::CONNECTED;
763
763
  }
@@ -141,13 +141,29 @@ bool WiFiComponent::wifi_scan_start_(bool passive) {
141
141
 
142
142
  #ifdef USE_WIFI_AP
143
143
  bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
144
- // TODO:
145
- return false;
144
+ esphome::network::IPAddress ip_address, gateway, subnet, dns;
145
+ if (manual_ip.has_value()) {
146
+ ip_address = manual_ip->static_ip;
147
+ gateway = manual_ip->gateway;
148
+ subnet = manual_ip->subnet;
149
+ dns = manual_ip->static_ip;
150
+ } else {
151
+ ip_address = network::IPAddress(192, 168, 4, 1);
152
+ gateway = network::IPAddress(192, 168, 4, 1);
153
+ subnet = network::IPAddress(255, 255, 255, 0);
154
+ dns = network::IPAddress(192, 168, 4, 1);
155
+ }
156
+ WiFi.config(ip_address, dns, gateway, subnet);
157
+ return true;
146
158
  }
147
159
 
148
160
  bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
149
161
  if (!this->wifi_mode_({}, true))
150
162
  return false;
163
+ if (!this->wifi_ap_ip_config_(ap.get_manual_ip())) {
164
+ ESP_LOGV(TAG, "wifi_ap_ip_config_ failed!");
165
+ return false;
166
+ }
151
167
 
152
168
  WiFi.beginAP(ap.get_ssid().c_str(), ap.get_password().c_str(), ap.get_channel().value_or(1));
153
169
 
@@ -132,7 +132,7 @@ async def to_code(config):
132
132
  # the '+1' modifier is relative to the device's own address that will
133
133
  # be automatically added to the provided list.
134
134
  cg.add_build_flag(f"-DCONFIG_WIREGUARD_MAX_SRC_IPS={len(allowed_ips) + 1}")
135
- cg.add_library("droscy/esp_wireguard", "0.4.1")
135
+ cg.add_library("droscy/esp_wireguard", "0.4.2")
136
136
 
137
137
  await cg.register_component(var, config)
138
138
 
@@ -27,7 +27,13 @@ CONFIG_SCHEMA = cv.All(
27
27
  cv.Optional(CONF_INITIAL_VALUE, default=1.0): cv.float_range(
28
28
  min=0.01, max=1.0
29
29
  ),
30
- cv.Optional(CONF_STEP_DELAY, default=1): cv.int_range(min=1, max=100),
30
+ cv.Optional(CONF_STEP_DELAY, default="1us"): cv.All(
31
+ cv.positive_time_period_microseconds,
32
+ cv.Range(
33
+ min=cv.TimePeriod(microseconds=1),
34
+ max=cv.TimePeriod(microseconds=100),
35
+ ),
36
+ ),
31
37
  }
32
38
  )
33
39
  )
esphome/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants used by esphome."""
2
2
 
3
- __version__ = "2024.6.6"
3
+ __version__ = "2024.7.0b1"
4
4
 
5
5
  ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
6
6
  VALID_SUBSTITUTIONS_CHARACTERS = (
@@ -1072,6 +1072,7 @@ DEVICE_CLASS_BUTTON = "button"
1072
1072
  DEVICE_CLASS_CARBON_DIOXIDE = "carbon_dioxide"
1073
1073
  DEVICE_CLASS_CARBON_MONOXIDE = "carbon_monoxide"
1074
1074
  DEVICE_CLASS_COLD = "cold"
1075
+ DEVICE_CLASS_CONDUCTIVITY = "conductivity"
1075
1076
  DEVICE_CLASS_CONNECTIVITY = "connectivity"
1076
1077
  DEVICE_CLASS_CURRENT = "current"
1077
1078
  DEVICE_CLASS_CURTAIN = "curtain"
esphome/core/defines.h CHANGED
@@ -86,6 +86,7 @@
86
86
  #define USE_ESP32_BLE_SERVER
87
87
  #define USE_ESP32_CAMERA
88
88
  #define USE_IMPROV
89
+ #define USE_MICRO_WAKE_WORD_VAD
89
90
  #define USE_MICROPHONE
90
91
  #define USE_PSRAM
91
92
  #define USE_SOCKET_IMPL_BSD_SOCKETS
esphome/core/helpers.cpp CHANGED
@@ -93,7 +93,7 @@ std::string to_string(long double value) { return str_snprintf("%Lf", 32, value)
93
93
  // Mathematics
94
94
 
95
95
  float lerp(float completion, float start, float end) { return start + (end - start) * completion; }
96
- uint8_t crc8(uint8_t *data, uint8_t len) {
96
+ uint8_t crc8(const uint8_t *data, uint8_t len) {
97
97
  uint8_t crc = 0;
98
98
 
99
99
  while ((len--) != 0u) {
esphome/core/helpers.h CHANGED
@@ -155,7 +155,7 @@ template<typename T, typename U> T remap(U value, U min, U max, T min_out, T max
155
155
  }
156
156
 
157
157
  /// Calculate a CRC-8 checksum of \p data with size \p len.
158
- uint8_t crc8(uint8_t *data, uint8_t len);
158
+ uint8_t crc8(const uint8_t *data, uint8_t len);
159
159
 
160
160
  /// Calculate a CRC-16 checksum of \p data with size \p len.
161
161
  uint16_t crc16(const uint8_t *data, uint16_t len, uint16_t crc = 0xffff, uint16_t reverse_poly = 0xa001,
esphome/external_files.py CHANGED
@@ -7,6 +7,7 @@ from datetime import datetime
7
7
  import requests
8
8
  import esphome.config_validation as cv
9
9
  from esphome.core import CORE, TimePeriodSeconds
10
+ from esphome.const import __version__
10
11
 
11
12
  _LOGGER = logging.getLogger(__name__)
12
13
  CODEOWNERS = ["@landonr"]
@@ -75,3 +76,28 @@ def compute_local_file_dir(domain: str) -> Path:
75
76
  base_directory.mkdir(parents=True, exist_ok=True)
76
77
 
77
78
  return base_directory
79
+
80
+
81
+ def download_content(url: str, path: Path, timeout=NETWORK_TIMEOUT) -> None:
82
+ if not has_remote_file_changed(url, path):
83
+ _LOGGER.debug("Remote file has not changed %s", url)
84
+ return
85
+
86
+ _LOGGER.debug(
87
+ "Remote file has changed, downloading from %s to %s",
88
+ url,
89
+ path,
90
+ )
91
+
92
+ try:
93
+ req = requests.get(
94
+ url,
95
+ timeout=timeout,
96
+ headers={"User-agent": f"ESPHome/{__version__} (https://esphome.io)"},
97
+ )
98
+ req.raise_for_status()
99
+ except requests.exceptions.RequestException as e:
100
+ raise cv.Invalid(f"Could not download from {url}: {e}")
101
+
102
+ path.parent.mkdir(parents=True, exist_ok=True)
103
+ path.write_bytes(req.content)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: esphome
3
- Version: 2024.6.6
3
+ Version: 2024.7.0b1
4
4
  Summary: Make creating custom firmwares for ESP32/ESP8266 super easy.
5
5
  Author-email: The ESPHome Authors <esphome@nabucasa.com>
6
6
  License: MIT