esphome 2025.5.0b2__py3-none-any.whl → 2025.5.0b4__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 (104) hide show
  1. esphome/__main__.py +16 -14
  2. esphome/components/api/api_connection.cpp +339 -652
  3. esphome/components/api/api_connection.h +251 -57
  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/__init__.py +1 -1
  33. esphome/components/esp32_camera/esp32_camera.cpp +2 -10
  34. esphome/components/esp32_camera/esp32_camera.h +1 -1
  35. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  36. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  37. esphome/components/ethernet/ethernet_component.cpp +1 -1
  38. esphome/components/feedback/feedback_cover.cpp +2 -1
  39. esphome/components/fujitsu_general/climate.py +1 -1
  40. esphome/components/gcja5/gcja5.cpp +2 -1
  41. esphome/components/gps/__init__.py +37 -16
  42. esphome/components/gps/gps.cpp +33 -17
  43. esphome/components/gps/gps.h +16 -15
  44. esphome/components/gree/climate.py +1 -1
  45. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  46. esphome/components/heatpumpir/climate.py +1 -1
  47. esphome/components/hitachi_ac344/climate.py +1 -1
  48. esphome/components/hitachi_ac424/climate.py +1 -1
  49. esphome/components/hte501/sensor.py +6 -6
  50. esphome/components/hyt271/sensor.py +6 -6
  51. esphome/components/kuntze/kuntze.cpp +2 -1
  52. esphome/components/logger/__init__.py +1 -0
  53. esphome/components/logger/logger.cpp +53 -32
  54. esphome/components/logger/logger.h +55 -5
  55. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  56. esphome/components/max7219digit/max7219digit.cpp +2 -1
  57. esphome/components/mhz19/sensor.py +11 -7
  58. esphome/components/midea_ir/climate.py +1 -1
  59. esphome/components/mitsubishi/climate.py +1 -1
  60. esphome/components/modbus/modbus.cpp +2 -1
  61. esphome/components/mqtt/mqtt_client.cpp +1 -1
  62. esphome/components/ms5611/sensor.py +6 -6
  63. esphome/components/ms8607/sensor.py +3 -3
  64. esphome/components/noblex/climate.py +1 -1
  65. esphome/components/pmsx003/pmsx003.cpp +2 -1
  66. esphome/components/pzem004t/pzem004t.cpp +2 -1
  67. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  68. esphome/components/sds011/sds011.cpp +2 -1
  69. esphome/components/sen5x/sen5x.cpp +55 -36
  70. esphome/components/senseair/sensor.py +3 -3
  71. esphome/components/sgp30/sensor.py +14 -16
  72. esphome/components/shtcx/sensor.py +6 -6
  73. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  74. esphome/components/sprinkler/sprinkler.cpp +6 -5
  75. esphome/components/t6615/sensor.py +3 -3
  76. esphome/components/t6615/t6615.cpp +2 -1
  77. esphome/components/tcl112/climate.py +1 -1
  78. esphome/components/time_based/time_based_cover.cpp +2 -1
  79. esphome/components/toshiba/climate.py +1 -1
  80. esphome/components/uart/switch/uart_switch.cpp +2 -1
  81. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  82. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  83. esphome/components/weikai/weikai.cpp +0 -52
  84. esphome/components/whirlpool/climate.py +1 -1
  85. esphome/components/whynter/climate.py +1 -1
  86. esphome/components/zhlt01/climate.py +1 -1
  87. esphome/config.py +13 -13
  88. esphome/const.py +1 -1
  89. esphome/core/application.cpp +26 -10
  90. esphome/core/application.h +5 -1
  91. esphome/core/component.cpp +10 -5
  92. esphome/core/component.h +5 -1
  93. esphome/core/doxygen.h +13 -0
  94. esphome/core/scheduler.cpp +4 -1
  95. esphome/log.py +15 -19
  96. esphome/mqtt.py +2 -2
  97. esphome/voluptuous_schema.py +3 -1
  98. esphome/wizard.py +45 -35
  99. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b4.dist-info}/METADATA +1 -1
  100. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b4.dist-info}/RECORD +104 -103
  101. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b4.dist-info}/WHEEL +0 -0
  102. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b4.dist-info}/entry_points.txt +0 -0
  103. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b4.dist-info}/licenses/LICENSE +0 -0
  104. {esphome-2025.5.0b2.dist-info → esphome-2025.5.0b4.dist-info}/top_level.txt +0 -0
@@ -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;
@@ -296,7 +296,7 @@ async def to_code(config):
296
296
  add_idf_component(
297
297
  name="esp32-camera",
298
298
  repo="https://github.com/espressif/esp32-camera.git",
299
- ref="v2.0.9",
299
+ ref="v2.0.15",
300
300
  )
301
301
 
302
302
  for conf in config.get(CONF_ON_STREAM_START, []):
@@ -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
 
@@ -54,11 +55,7 @@ void ESP32Camera::dump_config() {
54
55
  ESP_LOGCONFIG(TAG, " HREF Pin: %d", conf.pin_href);
55
56
  ESP_LOGCONFIG(TAG, " Pixel Clock Pin: %d", conf.pin_pclk);
56
57
  ESP_LOGCONFIG(TAG, " External Clock: Pin:%d Frequency:%u", conf.pin_xclk, conf.xclk_freq_hz);
57
- #ifdef USE_ESP_IDF // Temporary until the espressif/esp32-camera library is updated
58
- ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sscb_sda, conf.pin_sscb_scl);
59
- #else
60
58
  ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sccb_sda, conf.pin_sccb_scl);
61
- #endif
62
59
  ESP_LOGCONFIG(TAG, " Reset Pin: %d", conf.pin_reset);
63
60
  switch (this->config_.frame_size) {
64
61
  case FRAMESIZE_QQVGA:
@@ -162,7 +159,7 @@ void ESP32Camera::loop() {
162
159
  }
163
160
 
164
161
  // request idle image every idle_update_interval
165
- const uint32_t now = millis();
162
+ const uint32_t now = App.get_loop_component_start_time();
166
163
  if (this->idle_update_interval_ != 0 && now - this->last_idle_request_ > this->idle_update_interval_) {
167
164
  this->last_idle_request_ = now;
168
165
  this->request_image(IDLE);
@@ -238,13 +235,8 @@ void ESP32Camera::set_external_clock(uint8_t pin, uint32_t frequency) {
238
235
  this->config_.xclk_freq_hz = frequency;
239
236
  }
240
237
  void ESP32Camera::set_i2c_pins(uint8_t sda, uint8_t scl) {
241
- #ifdef USE_ESP_IDF // Temporary until the espressif/esp32-camera library is updated
242
- this->config_.pin_sscb_sda = sda;
243
- this->config_.pin_sscb_scl = scl;
244
- #else
245
238
  this->config_.pin_sccb_sda = sda;
246
239
  this->config_.pin_sccb_scl = scl;
247
- #endif
248
240
  }
249
241
  void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
250
242
  void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }
@@ -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:
@@ -1,6 +1,7 @@
1
1
  #include "feedback_cover.h"
2
2
  #include "esphome/core/hal.h"
3
3
  #include "esphome/core/log.h"
4
+ #include "esphome/core/application.h"
4
5
 
5
6
  namespace esphome {
6
7
  namespace feedback {
@@ -220,7 +221,7 @@ void FeedbackCover::set_open_obstacle_sensor(binary_sensor::BinarySensor *open_o
220
221
  void FeedbackCover::loop() {
221
222
  if (this->current_operation == COVER_OPERATION_IDLE)
222
223
  return;
223
- const uint32_t now = millis();
224
+ const uint32_t now = App.get_loop_component_start_time();
224
225
 
225
226
  // Recompute position every loop cycle
226
227
  this->recompute_position_();
@@ -8,7 +8,7 @@ FujitsuGeneralClimate = fujitsu_general_ns.class_(
8
8
  "FujitsuGeneralClimate", climate_ir.ClimateIR
9
9
  )
10
10
 
11
- CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(FujitsuGeneralClimate)
11
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(FujitsuGeneralClimate)
12
12
 
13
13
 
14
14
  async def to_code(config):
@@ -6,6 +6,7 @@
6
6
  */
7
7
  #include "gcja5.h"
8
8
  #include "esphome/core/log.h"
9
+ #include "esphome/core/application.h"
9
10
  #include <cstring>
10
11
 
11
12
  namespace esphome {
@@ -16,7 +17,7 @@ static const char *const TAG = "gcja5";
16
17
  void GCJA5Component::setup() { ESP_LOGCONFIG(TAG, "Setting up gcja5..."); }
17
18
 
18
19
  void GCJA5Component::loop() {
19
- const uint32_t now = millis();
20
+ const uint32_t now = App.get_loop_component_start_time();
20
21
  if (now - this->last_transmission_ >= 500) {
21
22
  // last transmission too long ago. Reset RX index.
22
23
  this->rx_message_.clear();