esphome 2025.5.0b2__py3-none-any.whl → 2025.5.0b3__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 (101) hide show
  1. esphome/__main__.py +16 -14
  2. esphome/components/api/api_connection.cpp +4 -3
  3. esphome/components/api/api_connection.h +8 -1
  4. esphome/components/api/api_frame_helper.cpp +136 -49
  5. esphome/components/api/api_frame_helper.h +49 -6
  6. esphome/components/api/proto.h +48 -8
  7. esphome/components/ballu/climate.py +1 -1
  8. esphome/components/bedjet/bedjet_hub.cpp +1 -0
  9. esphome/components/binary_sensor/binary_sensor.cpp +10 -6
  10. esphome/components/binary_sensor/binary_sensor.h +1 -1
  11. esphome/components/binary_sensor/filter.cpp +21 -21
  12. esphome/components/binary_sensor/filter.h +10 -10
  13. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -1
  14. esphome/components/ccs811/sensor.py +9 -6
  15. esphome/components/climate_ir/__init__.py +3 -3
  16. esphome/components/climate_ir_lg/climate.py +1 -1
  17. esphome/components/coolix/climate.py +1 -1
  18. esphome/components/cse7766/cse7766.cpp +2 -1
  19. esphome/components/current_based/current_based_cover.cpp +2 -1
  20. esphome/components/daikin/climate.py +1 -1
  21. esphome/components/daikin_arc/climate.py +1 -1
  22. esphome/components/daikin_brc/climate.py +1 -1
  23. esphome/components/daly_bms/daly_bms.cpp +2 -1
  24. esphome/components/debug/debug_component.cpp +1 -1
  25. esphome/components/delonghi/climate.py +1 -1
  26. esphome/components/dps310/sensor.py +6 -6
  27. esphome/components/ee895/sensor.py +9 -9
  28. esphome/components/emmeti/climate.py +1 -1
  29. esphome/components/endstop/endstop_cover.cpp +2 -1
  30. esphome/components/ens160_base/__init__.py +12 -9
  31. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  32. esphome/components/esp32_camera/esp32_camera.cpp +2 -1
  33. esphome/components/esp32_camera/esp32_camera.h +1 -1
  34. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  35. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  36. esphome/components/ethernet/ethernet_component.cpp +1 -1
  37. esphome/components/feedback/feedback_cover.cpp +2 -1
  38. esphome/components/fujitsu_general/climate.py +1 -1
  39. esphome/components/gcja5/gcja5.cpp +2 -1
  40. esphome/components/gps/__init__.py +37 -16
  41. esphome/components/gps/gps.cpp +33 -17
  42. esphome/components/gps/gps.h +16 -15
  43. esphome/components/gree/climate.py +1 -1
  44. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  45. esphome/components/heatpumpir/climate.py +1 -1
  46. esphome/components/hitachi_ac344/climate.py +1 -1
  47. esphome/components/hitachi_ac424/climate.py +1 -1
  48. esphome/components/hte501/sensor.py +6 -6
  49. esphome/components/hyt271/sensor.py +6 -6
  50. esphome/components/kuntze/kuntze.cpp +2 -1
  51. esphome/components/logger/__init__.py +1 -0
  52. esphome/components/logger/logger.cpp +53 -32
  53. esphome/components/logger/logger.h +55 -5
  54. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  55. esphome/components/max7219digit/max7219digit.cpp +2 -1
  56. esphome/components/mhz19/sensor.py +11 -7
  57. esphome/components/midea_ir/climate.py +1 -1
  58. esphome/components/mitsubishi/climate.py +1 -1
  59. esphome/components/modbus/modbus.cpp +2 -1
  60. esphome/components/mqtt/mqtt_client.cpp +1 -1
  61. esphome/components/ms5611/sensor.py +6 -6
  62. esphome/components/ms8607/sensor.py +3 -3
  63. esphome/components/noblex/climate.py +1 -1
  64. esphome/components/pmsx003/pmsx003.cpp +2 -1
  65. esphome/components/pzem004t/pzem004t.cpp +2 -1
  66. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  67. esphome/components/sds011/sds011.cpp +2 -1
  68. esphome/components/sen5x/sen5x.cpp +55 -36
  69. esphome/components/senseair/sensor.py +3 -3
  70. esphome/components/sgp30/sensor.py +14 -16
  71. esphome/components/shtcx/sensor.py +6 -6
  72. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  73. esphome/components/sprinkler/sprinkler.cpp +6 -5
  74. esphome/components/t6615/sensor.py +3 -3
  75. esphome/components/t6615/t6615.cpp +2 -1
  76. esphome/components/tcl112/climate.py +1 -1
  77. esphome/components/time_based/time_based_cover.cpp +2 -1
  78. esphome/components/toshiba/climate.py +1 -1
  79. esphome/components/uart/switch/uart_switch.cpp +2 -1
  80. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  81. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  82. esphome/components/whirlpool/climate.py +1 -1
  83. esphome/components/whynter/climate.py +1 -1
  84. esphome/components/zhlt01/climate.py +1 -1
  85. esphome/config.py +13 -13
  86. esphome/const.py +1 -1
  87. esphome/core/application.cpp +22 -10
  88. esphome/core/application.h +5 -1
  89. esphome/core/component.cpp +10 -5
  90. esphome/core/component.h +5 -1
  91. esphome/core/scheduler.cpp +4 -1
  92. esphome/log.py +15 -19
  93. esphome/mqtt.py +2 -2
  94. esphome/voluptuous_schema.py +3 -1
  95. esphome/wizard.py +45 -35
  96. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b3.dist-info}/METADATA +1 -1
  97. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b3.dist-info}/RECORD +101 -101
  98. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b3.dist-info}/WHEEL +0 -0
  99. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b3.dist-info}/entry_points.txt +0 -0
  100. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b3.dist-info}/licenses/LICENSE +0 -0
  101. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b3.dist-info}/top_level.txt +0 -0
@@ -15,17 +15,21 @@ void BinarySensor::publish_state(bool state) {
15
15
  if (!this->publish_dedup_.next(state))
16
16
  return;
17
17
  if (this->filter_list_ == nullptr) {
18
- this->send_state_internal(state);
18
+ this->send_state_internal(state, false);
19
19
  } else {
20
- this->filter_list_->input(state);
20
+ this->filter_list_->input(state, false);
21
21
  }
22
22
  }
23
23
  void BinarySensor::publish_initial_state(bool state) {
24
- this->has_state_ = false;
25
- this->publish_state(state);
24
+ if (!this->publish_dedup_.next(state))
25
+ return;
26
+ if (this->filter_list_ == nullptr) {
27
+ this->send_state_internal(state, true);
28
+ } else {
29
+ this->filter_list_->input(state, true);
30
+ }
26
31
  }
27
- void BinarySensor::send_state_internal(bool state) {
28
- bool is_initial = !this->has_state_;
32
+ void BinarySensor::send_state_internal(bool state, bool is_initial) {
29
33
  if (is_initial) {
30
34
  ESP_LOGD(TAG, "'%s': Sending initial state %s", this->get_name().c_str(), ONOFF(state));
31
35
  } else {
@@ -67,7 +67,7 @@ class BinarySensor : public EntityBase, public EntityBase_DeviceClass {
67
67
 
68
68
  // ========== INTERNAL METHODS ==========
69
69
  // (In most use cases you won't need these)
70
- void send_state_internal(bool state);
70
+ void send_state_internal(bool state, bool is_initial);
71
71
 
72
72
  /// Return whether this binary sensor has outputted a state.
73
73
  virtual bool has_state() const;
@@ -9,37 +9,37 @@ namespace binary_sensor {
9
9
 
10
10
  static const char *const TAG = "sensor.filter";
11
11
 
12
- void Filter::output(bool value) {
12
+ void Filter::output(bool value, bool is_initial) {
13
13
  if (!this->dedup_.next(value))
14
14
  return;
15
15
 
16
16
  if (this->next_ == nullptr) {
17
- this->parent_->send_state_internal(value);
17
+ this->parent_->send_state_internal(value, is_initial);
18
18
  } else {
19
- this->next_->input(value);
19
+ this->next_->input(value, is_initial);
20
20
  }
21
21
  }
22
- void Filter::input(bool value) {
23
- auto b = this->new_value(value);
22
+ void Filter::input(bool value, bool is_initial) {
23
+ auto b = this->new_value(value, is_initial);
24
24
  if (b.has_value()) {
25
- this->output(*b);
25
+ this->output(*b, is_initial);
26
26
  }
27
27
  }
28
28
 
29
- optional<bool> DelayedOnOffFilter::new_value(bool value) {
29
+ optional<bool> DelayedOnOffFilter::new_value(bool value, bool is_initial) {
30
30
  if (value) {
31
- this->set_timeout("ON_OFF", this->on_delay_.value(), [this]() { this->output(true); });
31
+ this->set_timeout("ON_OFF", this->on_delay_.value(), [this, is_initial]() { this->output(true, is_initial); });
32
32
  } else {
33
- this->set_timeout("ON_OFF", this->off_delay_.value(), [this]() { this->output(false); });
33
+ this->set_timeout("ON_OFF", this->off_delay_.value(), [this, is_initial]() { this->output(false, is_initial); });
34
34
  }
35
35
  return {};
36
36
  }
37
37
 
38
38
  float DelayedOnOffFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
39
39
 
40
- optional<bool> DelayedOnFilter::new_value(bool value) {
40
+ optional<bool> DelayedOnFilter::new_value(bool value, bool is_initial) {
41
41
  if (value) {
42
- this->set_timeout("ON", this->delay_.value(), [this]() { this->output(true); });
42
+ this->set_timeout("ON", this->delay_.value(), [this, is_initial]() { this->output(true, is_initial); });
43
43
  return {};
44
44
  } else {
45
45
  this->cancel_timeout("ON");
@@ -49,9 +49,9 @@ optional<bool> DelayedOnFilter::new_value(bool value) {
49
49
 
50
50
  float DelayedOnFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
51
51
 
52
- optional<bool> DelayedOffFilter::new_value(bool value) {
52
+ optional<bool> DelayedOffFilter::new_value(bool value, bool is_initial) {
53
53
  if (!value) {
54
- this->set_timeout("OFF", this->delay_.value(), [this]() { this->output(false); });
54
+ this->set_timeout("OFF", this->delay_.value(), [this, is_initial]() { this->output(false, is_initial); });
55
55
  return {};
56
56
  } else {
57
57
  this->cancel_timeout("OFF");
@@ -61,11 +61,11 @@ optional<bool> DelayedOffFilter::new_value(bool value) {
61
61
 
62
62
  float DelayedOffFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
63
63
 
64
- optional<bool> InvertFilter::new_value(bool value) { return !value; }
64
+ optional<bool> InvertFilter::new_value(bool value, bool is_initial) { return !value; }
65
65
 
66
66
  AutorepeatFilter::AutorepeatFilter(std::vector<AutorepeatFilterTiming> timings) : timings_(std::move(timings)) {}
67
67
 
68
- optional<bool> AutorepeatFilter::new_value(bool value) {
68
+ optional<bool> AutorepeatFilter::new_value(bool value, bool is_initial) {
69
69
  if (value) {
70
70
  // Ignore if already running
71
71
  if (this->active_timing_ != 0)
@@ -101,7 +101,7 @@ void AutorepeatFilter::next_timing_() {
101
101
 
102
102
  void AutorepeatFilter::next_value_(bool val) {
103
103
  const AutorepeatFilterTiming &timing = this->timings_[this->active_timing_ - 2];
104
- this->output(val);
104
+ this->output(val, false); // This is at least the second one so not initial
105
105
  this->set_timeout("ON_OFF", val ? timing.time_on : timing.time_off, [this, val]() { this->next_value_(!val); });
106
106
  }
107
107
 
@@ -109,18 +109,18 @@ float AutorepeatFilter::get_setup_priority() const { return setup_priority::HARD
109
109
 
110
110
  LambdaFilter::LambdaFilter(std::function<optional<bool>(bool)> f) : f_(std::move(f)) {}
111
111
 
112
- optional<bool> LambdaFilter::new_value(bool value) { return this->f_(value); }
112
+ optional<bool> LambdaFilter::new_value(bool value, bool is_initial) { return this->f_(value); }
113
113
 
114
- optional<bool> SettleFilter::new_value(bool value) {
114
+ optional<bool> SettleFilter::new_value(bool value, bool is_initial) {
115
115
  if (!this->steady_) {
116
- this->set_timeout("SETTLE", this->delay_.value(), [this, value]() {
116
+ this->set_timeout("SETTLE", this->delay_.value(), [this, value, is_initial]() {
117
117
  this->steady_ = true;
118
- this->output(value);
118
+ this->output(value, is_initial);
119
119
  });
120
120
  return {};
121
121
  } else {
122
122
  this->steady_ = false;
123
- this->output(value);
123
+ this->output(value, is_initial);
124
124
  this->set_timeout("SETTLE", this->delay_.value(), [this]() { this->steady_ = true; });
125
125
  return value;
126
126
  }
@@ -14,11 +14,11 @@ class BinarySensor;
14
14
 
15
15
  class Filter {
16
16
  public:
17
- virtual optional<bool> new_value(bool value) = 0;
17
+ virtual optional<bool> new_value(bool value, bool is_initial) = 0;
18
18
 
19
- void input(bool value);
19
+ void input(bool value, bool is_initial);
20
20
 
21
- void output(bool value);
21
+ void output(bool value, bool is_initial);
22
22
 
23
23
  protected:
24
24
  friend BinarySensor;
@@ -30,7 +30,7 @@ class Filter {
30
30
 
31
31
  class DelayedOnOffFilter : public Filter, public Component {
32
32
  public:
33
- optional<bool> new_value(bool value) override;
33
+ optional<bool> new_value(bool value, bool is_initial) override;
34
34
 
35
35
  float get_setup_priority() const override;
36
36
 
@@ -44,7 +44,7 @@ class DelayedOnOffFilter : public Filter, public Component {
44
44
 
45
45
  class DelayedOnFilter : public Filter, public Component {
46
46
  public:
47
- optional<bool> new_value(bool value) override;
47
+ optional<bool> new_value(bool value, bool is_initial) override;
48
48
 
49
49
  float get_setup_priority() const override;
50
50
 
@@ -56,7 +56,7 @@ class DelayedOnFilter : public Filter, public Component {
56
56
 
57
57
  class DelayedOffFilter : public Filter, public Component {
58
58
  public:
59
- optional<bool> new_value(bool value) override;
59
+ optional<bool> new_value(bool value, bool is_initial) override;
60
60
 
61
61
  float get_setup_priority() const override;
62
62
 
@@ -68,7 +68,7 @@ class DelayedOffFilter : public Filter, public Component {
68
68
 
69
69
  class InvertFilter : public Filter {
70
70
  public:
71
- optional<bool> new_value(bool value) override;
71
+ optional<bool> new_value(bool value, bool is_initial) override;
72
72
  };
73
73
 
74
74
  struct AutorepeatFilterTiming {
@@ -86,7 +86,7 @@ class AutorepeatFilter : public Filter, public Component {
86
86
  public:
87
87
  explicit AutorepeatFilter(std::vector<AutorepeatFilterTiming> timings);
88
88
 
89
- optional<bool> new_value(bool value) override;
89
+ optional<bool> new_value(bool value, bool is_initial) override;
90
90
 
91
91
  float get_setup_priority() const override;
92
92
 
@@ -102,7 +102,7 @@ class LambdaFilter : public Filter {
102
102
  public:
103
103
  explicit LambdaFilter(std::function<optional<bool>(bool)> f);
104
104
 
105
- optional<bool> new_value(bool value) override;
105
+ optional<bool> new_value(bool value, bool is_initial) override;
106
106
 
107
107
  protected:
108
108
  std::function<optional<bool>(bool)> f_;
@@ -110,7 +110,7 @@ class LambdaFilter : public Filter {
110
110
 
111
111
  class SettleFilter : public Filter, public Component {
112
112
  public:
113
- optional<bool> new_value(bool value) override;
113
+ optional<bool> new_value(bool value, bool is_initial) override;
114
114
 
115
115
  float get_setup_priority() const override;
116
116
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include "esphome/core/log.h"
4
4
  #include "esphome/core/macros.h"
5
+ #include "esphome/core/application.h"
5
6
 
6
7
  #ifdef USE_ESP32
7
8
 
@@ -177,7 +178,7 @@ void BluetoothProxy::loop() {
177
178
  // Flush any pending BLE advertisements that have been accumulated but not yet sent
178
179
  if (this->raw_advertisements_) {
179
180
  static uint32_t last_flush_time = 0;
180
- uint32_t now = millis();
181
+ uint32_t now = App.get_loop_component_start_time();
181
182
 
182
183
  // Flush accumulated advertisements every 100ms
183
184
  if (now - last_flush_time >= 100) {
@@ -32,14 +32,14 @@ CONFIG_SCHEMA = (
32
32
  cv.Schema(
33
33
  {
34
34
  cv.GenerateID(): cv.declare_id(CCS811Component),
35
- cv.Required(CONF_ECO2): sensor.sensor_schema(
35
+ cv.Optional(CONF_ECO2): sensor.sensor_schema(
36
36
  unit_of_measurement=UNIT_PARTS_PER_MILLION,
37
37
  icon=ICON_MOLECULE_CO2,
38
38
  accuracy_decimals=0,
39
39
  device_class=DEVICE_CLASS_CARBON_DIOXIDE,
40
40
  state_class=STATE_CLASS_MEASUREMENT,
41
41
  ),
42
- cv.Required(CONF_TVOC): sensor.sensor_schema(
42
+ cv.Optional(CONF_TVOC): sensor.sensor_schema(
43
43
  unit_of_measurement=UNIT_PARTS_PER_BILLION,
44
44
  icon=ICON_RADIATOR,
45
45
  accuracy_decimals=0,
@@ -64,10 +64,13 @@ async def to_code(config):
64
64
  await cg.register_component(var, config)
65
65
  await i2c.register_i2c_device(var, config)
66
66
 
67
- sens = await sensor.new_sensor(config[CONF_ECO2])
68
- cg.add(var.set_co2(sens))
69
- sens = await sensor.new_sensor(config[CONF_TVOC])
70
- cg.add(var.set_tvoc(sens))
67
+ if eco2_config := config.get(CONF_ECO2):
68
+ sens = await sensor.new_sensor(eco2_config)
69
+ cg.add(var.set_co2(sens))
70
+
71
+ if tvoc_config := config.get(CONF_TVOC):
72
+ sens = await sensor.new_sensor(tvoc_config)
73
+ cg.add(var.set_tvoc(sens))
71
74
 
72
75
  if version_config := config.get(CONF_VERSION):
73
76
  sens = await text_sensor.new_text_sensor(version_config)
@@ -40,7 +40,7 @@ def climate_ir_schema(
40
40
  )
41
41
 
42
42
 
43
- def climare_ir_with_receiver_schema(
43
+ def climate_ir_with_receiver_schema(
44
44
  class_: MockObjClass,
45
45
  ) -> cv.Schema:
46
46
  return climate_ir_schema(class_).extend(
@@ -59,7 +59,7 @@ def deprecated_schema_constant(config):
59
59
  type = str(id.type).split("::", maxsplit=1)[0]
60
60
  _LOGGER.warning(
61
61
  "Using `climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA` is deprecated and will be removed in ESPHome 2025.11.0. "
62
- "Please use `climate_ir.climare_ir_with_receiver_schema(...)` instead. "
62
+ "Please use `climate_ir.climate_ir_with_receiver_schema(...)` instead. "
63
63
  "If you are seeing this, report an issue to the external_component author and ask them to update it. "
64
64
  "https://developers.esphome.io/blog/2025/05/14/_schema-deprecations/. "
65
65
  "Component using this schema: %s",
@@ -68,7 +68,7 @@ def deprecated_schema_constant(config):
68
68
  return config
69
69
 
70
70
 
71
- CLIMATE_IR_WITH_RECEIVER_SCHEMA = climare_ir_with_receiver_schema(ClimateIR)
71
+ CLIMATE_IR_WITH_RECEIVER_SCHEMA = climate_ir_with_receiver_schema(ClimateIR)
72
72
  CLIMATE_IR_WITH_RECEIVER_SCHEMA.add_extra(deprecated_schema_constant)
73
73
 
74
74
 
@@ -13,7 +13,7 @@ CONF_BIT_HIGH = "bit_high"
13
13
  CONF_BIT_ONE_LOW = "bit_one_low"
14
14
  CONF_BIT_ZERO_LOW = "bit_zero_low"
15
15
 
16
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(LgIrClimate).extend(
16
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(LgIrClimate).extend(
17
17
  {
18
18
  cv.Optional(
19
19
  CONF_HEADER_HIGH, default="8000us"
@@ -7,7 +7,7 @@ CODEOWNERS = ["@glmnet"]
7
7
  coolix_ns = cg.esphome_ns.namespace("coolix")
8
8
  CoolixClimate = coolix_ns.class_("CoolixClimate", climate_ir.ClimateIR)
9
9
 
10
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(CoolixClimate)
10
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(CoolixClimate)
11
11
 
12
12
 
13
13
  async def to_code(config):
@@ -1,5 +1,6 @@
1
1
  #include "cse7766.h"
2
2
  #include "esphome/core/log.h"
3
+ #include "esphome/core/application.h"
3
4
 
4
5
  namespace esphome {
5
6
  namespace cse7766 {
@@ -7,7 +8,7 @@ namespace cse7766 {
7
8
  static const char *const TAG = "cse7766";
8
9
 
9
10
  void CSE7766Component::loop() {
10
- const uint32_t now = millis();
11
+ const uint32_t now = App.get_loop_component_start_time();
11
12
  if (now - this->last_transmission_ >= 500) {
12
13
  // last transmission too long ago. Reset RX index.
13
14
  this->raw_data_index_ = 0;
@@ -1,6 +1,7 @@
1
1
  #include "current_based_cover.h"
2
2
  #include "esphome/core/hal.h"
3
3
  #include "esphome/core/log.h"
4
+ #include "esphome/core/application.h"
4
5
  #include <cfloat>
5
6
 
6
7
  namespace esphome {
@@ -60,7 +61,7 @@ void CurrentBasedCover::loop() {
60
61
  if (this->current_operation == COVER_OPERATION_IDLE)
61
62
  return;
62
63
 
63
- const uint32_t now = millis();
64
+ const uint32_t now = App.get_loop_component_start_time();
64
65
 
65
66
  if (this->current_operation == COVER_OPERATION_OPENING) {
66
67
  if (this->malfunction_detection_ && this->is_closing_()) { // Malfunction
@@ -6,7 +6,7 @@ AUTO_LOAD = ["climate_ir"]
6
6
  daikin_ns = cg.esphome_ns.namespace("daikin")
7
7
  DaikinClimate = daikin_ns.class_("DaikinClimate", climate_ir.ClimateIR)
8
8
 
9
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(DaikinClimate)
9
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(DaikinClimate)
10
10
 
11
11
 
12
12
  async def to_code(config):
@@ -6,7 +6,7 @@ AUTO_LOAD = ["climate_ir"]
6
6
  daikin_arc_ns = cg.esphome_ns.namespace("daikin_arc")
7
7
  DaikinArcClimate = daikin_arc_ns.class_("DaikinArcClimate", climate_ir.ClimateIR)
8
8
 
9
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(DaikinArcClimate)
9
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(DaikinArcClimate)
10
10
 
11
11
 
12
12
  async def to_code(config):
@@ -9,7 +9,7 @@ daikin_brc_ns = cg.esphome_ns.namespace("daikin_brc")
9
9
  DaikinBrcClimate = daikin_brc_ns.class_("DaikinBrcClimate", climate_ir.ClimateIR)
10
10
 
11
11
 
12
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(DaikinBrcClimate).extend(
12
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(DaikinBrcClimate).extend(
13
13
  {
14
14
  cv.Optional(CONF_USE_FAHRENHEIT, default=False): cv.boolean,
15
15
  }
@@ -1,6 +1,7 @@
1
1
  #include "daly_bms.h"
2
2
  #include <vector>
3
3
  #include "esphome/core/log.h"
4
+ #include "esphome/core/application.h"
4
5
 
5
6
  namespace esphome {
6
7
  namespace daly_bms {
@@ -32,7 +33,7 @@ void DalyBmsComponent::update() {
32
33
  }
33
34
 
34
35
  void DalyBmsComponent::loop() {
35
- const uint32_t now = millis();
36
+ const uint32_t now = App.get_loop_component_start_time();
36
37
  if (this->receiving_ && (now - this->last_transmission_ >= 200)) {
37
38
  // last transmission too long ago. Reset RX index.
38
39
  ESP_LOGW(TAG, "Last transmission too long ago. Reset RX index.");
@@ -70,7 +70,7 @@ void DebugComponent::loop() {
70
70
  #ifdef USE_SENSOR
71
71
  // calculate loop time - from last call to this one
72
72
  if (this->loop_time_sensor_ != nullptr) {
73
- uint32_t now = millis();
73
+ uint32_t now = App.get_loop_component_start_time();
74
74
  uint32_t loop_time = now - this->last_loop_timetag_;
75
75
  this->max_loop_time_ = std::max(this->max_loop_time_, loop_time);
76
76
  this->last_loop_timetag_ = now;
@@ -6,7 +6,7 @@ AUTO_LOAD = ["climate_ir"]
6
6
  delonghi_ns = cg.esphome_ns.namespace("delonghi")
7
7
  DelonghiClimate = delonghi_ns.class_("DelonghiClimate", climate_ir.ClimateIR)
8
8
 
9
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(DelonghiClimate)
9
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(DelonghiClimate)
10
10
 
11
11
 
12
12
  async def to_code(config):
@@ -27,14 +27,14 @@ CONFIG_SCHEMA = (
27
27
  cv.Schema(
28
28
  {
29
29
  cv.GenerateID(): cv.declare_id(DPS310Component),
30
- cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
30
+ cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
31
31
  unit_of_measurement=UNIT_CELSIUS,
32
32
  icon=ICON_THERMOMETER,
33
33
  accuracy_decimals=1,
34
34
  device_class=DEVICE_CLASS_TEMPERATURE,
35
35
  state_class=STATE_CLASS_MEASUREMENT,
36
36
  ),
37
- cv.Required(CONF_PRESSURE): sensor.sensor_schema(
37
+ cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
38
38
  unit_of_measurement=UNIT_HECTOPASCAL,
39
39
  icon=ICON_GAUGE,
40
40
  accuracy_decimals=1,
@@ -53,10 +53,10 @@ async def to_code(config):
53
53
  await cg.register_component(var, config)
54
54
  await i2c.register_i2c_device(var, config)
55
55
 
56
- if CONF_TEMPERATURE in config:
57
- sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
56
+ if temperature := config.get(CONF_TEMPERATURE):
57
+ sens = await sensor.new_sensor(temperature)
58
58
  cg.add(var.set_temperature_sensor(sens))
59
59
 
60
- if CONF_PRESSURE in config:
61
- sens = await sensor.new_sensor(config[CONF_PRESSURE])
60
+ if pressure := config.get(CONF_PRESSURE):
61
+ sens = await sensor.new_sensor(pressure)
62
62
  cg.add(var.set_pressure_sensor(sens))
@@ -26,19 +26,19 @@ CONFIG_SCHEMA = (
26
26
  cv.Schema(
27
27
  {
28
28
  cv.GenerateID(): cv.declare_id(EE895Component),
29
- cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
29
+ cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
30
30
  unit_of_measurement=UNIT_CELSIUS,
31
31
  accuracy_decimals=1,
32
32
  device_class=DEVICE_CLASS_TEMPERATURE,
33
33
  state_class=STATE_CLASS_MEASUREMENT,
34
34
  ),
35
- cv.Required(CONF_CO2): sensor.sensor_schema(
35
+ cv.Optional(CONF_CO2): sensor.sensor_schema(
36
36
  unit_of_measurement=UNIT_PARTS_PER_MILLION,
37
37
  icon=ICON_MOLECULE_CO2,
38
38
  accuracy_decimals=0,
39
39
  state_class=STATE_CLASS_MEASUREMENT,
40
40
  ),
41
- cv.Required(CONF_PRESSURE): sensor.sensor_schema(
41
+ cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
42
42
  unit_of_measurement=UNIT_HECTOPASCAL,
43
43
  accuracy_decimals=1,
44
44
  device_class=DEVICE_CLASS_PRESSURE,
@@ -56,14 +56,14 @@ async def to_code(config):
56
56
  await cg.register_component(var, config)
57
57
  await i2c.register_i2c_device(var, config)
58
58
 
59
- if CONF_TEMPERATURE in config:
60
- sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
59
+ if temperature := config.get(CONF_TEMPERATURE):
60
+ sens = await sensor.new_sensor(temperature)
61
61
  cg.add(var.set_temperature_sensor(sens))
62
62
 
63
- if CONF_CO2 in config:
64
- sens = await sensor.new_sensor(config[CONF_CO2])
63
+ if co2 := config.get(CONF_CO2):
64
+ sens = await sensor.new_sensor(co2)
65
65
  cg.add(var.set_co2_sensor(sens))
66
66
 
67
- if CONF_PRESSURE in config:
68
- sens = await sensor.new_sensor(config[CONF_PRESSURE])
67
+ if pressure := config.get(CONF_PRESSURE):
68
+ sens = await sensor.new_sensor(pressure)
69
69
  cg.add(var.set_pressure_sensor(sens))
@@ -7,7 +7,7 @@ AUTO_LOAD = ["climate_ir"]
7
7
  emmeti_ns = cg.esphome_ns.namespace("emmeti")
8
8
  EmmetiClimate = emmeti_ns.class_("EmmetiClimate", climate_ir.ClimateIR)
9
9
 
10
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(EmmetiClimate)
10
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(EmmetiClimate)
11
11
 
12
12
 
13
13
  async def to_code(config):
@@ -1,6 +1,7 @@
1
1
  #include "endstop_cover.h"
2
2
  #include "esphome/core/log.h"
3
3
  #include "esphome/core/hal.h"
4
+ #include "esphome/core/application.h"
4
5
 
5
6
  namespace esphome {
6
7
  namespace endstop {
@@ -65,7 +66,7 @@ void EndstopCover::loop() {
65
66
  if (this->current_operation == COVER_OPERATION_IDLE)
66
67
  return;
67
68
 
68
- const uint32_t now = millis();
69
+ const uint32_t now = App.get_loop_component_start_time();
69
70
 
70
71
  if (this->current_operation == COVER_OPERATION_OPENING && this->is_open_()) {
71
72
  float dur = (now - this->start_dir_time_) / 1e3f;
@@ -28,21 +28,21 @@ UNIT_INDEX = "index"
28
28
 
29
29
  CONFIG_SCHEMA_BASE = cv.Schema(
30
30
  {
31
- cv.Required(CONF_ECO2): sensor.sensor_schema(
31
+ cv.Optional(CONF_ECO2): sensor.sensor_schema(
32
32
  unit_of_measurement=UNIT_PARTS_PER_MILLION,
33
33
  icon=ICON_MOLECULE_CO2,
34
34
  accuracy_decimals=0,
35
35
  device_class=DEVICE_CLASS_CARBON_DIOXIDE,
36
36
  state_class=STATE_CLASS_MEASUREMENT,
37
37
  ),
38
- cv.Required(CONF_TVOC): sensor.sensor_schema(
38
+ cv.Optional(CONF_TVOC): sensor.sensor_schema(
39
39
  unit_of_measurement=UNIT_PARTS_PER_BILLION,
40
40
  icon=ICON_RADIATOR,
41
41
  accuracy_decimals=0,
42
42
  device_class=DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
43
43
  state_class=STATE_CLASS_MEASUREMENT,
44
44
  ),
45
- cv.Required(CONF_AQI): sensor.sensor_schema(
45
+ cv.Optional(CONF_AQI): sensor.sensor_schema(
46
46
  icon=ICON_CHEMICAL_WEAPON,
47
47
  accuracy_decimals=0,
48
48
  device_class=DEVICE_CLASS_AQI,
@@ -62,12 +62,15 @@ async def to_code_base(config):
62
62
  var = cg.new_Pvariable(config[CONF_ID])
63
63
  await cg.register_component(var, config)
64
64
 
65
- sens = await sensor.new_sensor(config[CONF_ECO2])
66
- cg.add(var.set_co2(sens))
67
- sens = await sensor.new_sensor(config[CONF_TVOC])
68
- cg.add(var.set_tvoc(sens))
69
- sens = await sensor.new_sensor(config[CONF_AQI])
70
- cg.add(var.set_aqi(sens))
65
+ if eco2_config := config.get(CONF_ECO2):
66
+ sens = await sensor.new_sensor(eco2_config)
67
+ cg.add(var.set_co2(sens))
68
+ if tvoc_config := config.get(CONF_TVOC):
69
+ sens = await sensor.new_sensor(tvoc_config)
70
+ cg.add(var.set_tvoc(sens))
71
+ if aqi_config := config.get(CONF_AQI):
72
+ sens = await sensor.new_sensor(aqi_config)
73
+ cg.add(var.set_aqi(sens))
71
74
 
72
75
  if compensation_config := config.get(CONF_COMPENSATION):
73
76
  sens = await cg.get_variable(compensation_config[CONF_TEMPERATURE])
@@ -6,6 +6,7 @@
6
6
  #include <cstring>
7
7
  #include "ble_uuid.h"
8
8
  #include "esphome/core/log.h"
9
+ #include "esphome/core/application.h"
9
10
 
10
11
  namespace esphome {
11
12
  namespace esp32_ble {
@@ -143,7 +144,7 @@ void BLEAdvertising::loop() {
143
144
  if (this->raw_advertisements_callbacks_.empty()) {
144
145
  return;
145
146
  }
146
- const uint32_t now = millis();
147
+ const uint32_t now = App.get_loop_component_start_time();
147
148
  if (now - this->last_advertisement_time_ > this->advertising_cycle_time_) {
148
149
  this->stop();
149
150
  this->current_adv_index_ += 1;
@@ -3,6 +3,7 @@
3
3
  #include "esp32_camera.h"
4
4
  #include "esphome/core/log.h"
5
5
  #include "esphome/core/hal.h"
6
+ #include "esphome/core/application.h"
6
7
 
7
8
  #include <freertos/task.h>
8
9
 
@@ -162,7 +163,7 @@ void ESP32Camera::loop() {
162
163
  }
163
164
 
164
165
  // request idle image every idle_update_interval
165
- const uint32_t now = millis();
166
+ const uint32_t now = App.get_loop_component_start_time();
166
167
  if (this->idle_update_interval_ != 0 && now - this->last_idle_request_ > this->idle_update_interval_) {
167
168
  this->last_idle_request_ = now;
168
169
  this->request_image(IDLE);
@@ -106,7 +106,7 @@ class CameraImageReader {
106
106
  };
107
107
 
108
108
  /* ---------------- ESP32Camera class ---------------- */
109
- class ESP32Camera : public Component, public EntityBase {
109
+ class ESP32Camera : public EntityBase, public Component {
110
110
  public:
111
111
  ESP32Camera();
112
112
 
@@ -92,7 +92,7 @@ void ESP32ImprovComponent::loop() {
92
92
 
93
93
  if (!this->incoming_data_.empty())
94
94
  this->process_incoming_data_();
95
- uint32_t now = millis();
95
+ uint32_t now = App.get_loop_component_start_time();
96
96
 
97
97
  switch (this->state_) {
98
98
  case improv::STATE_STOPPED:
@@ -288,7 +288,7 @@ uint32_t ESP32TouchComponent::component_touch_pad_read(touch_pad_t tp) {
288
288
  }
289
289
 
290
290
  void ESP32TouchComponent::loop() {
291
- const uint32_t now = millis();
291
+ const uint32_t now = App.get_loop_component_start_time();
292
292
  bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
293
293
  for (auto *child : this->children_) {
294
294
  child->value_ = this->component_touch_pad_read(child->get_touch_pad());
@@ -240,7 +240,7 @@ void EthernetComponent::setup() {
240
240
  }
241
241
 
242
242
  void EthernetComponent::loop() {
243
- const uint32_t now = millis();
243
+ const uint32_t now = App.get_loop_component_start_time();
244
244
 
245
245
  switch (this->state_) {
246
246
  case EthernetComponentState::STOPPED: