esphome 2024.7.0b1__py3-none-any.whl → 2024.7.0b2__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 (29) hide show
  1. esphome/components/aht10/aht10.cpp +4 -2
  2. esphome/components/climate/climate.cpp +10 -6
  3. esphome/components/climate/climate_traits.h +3 -3
  4. esphome/components/esp32_can/canbus.py +3 -0
  5. esphome/components/ethernet/ethernet_component.cpp +5 -1
  6. esphome/components/gree/climate.py +1 -0
  7. esphome/components/gree/gree.cpp +11 -3
  8. esphome/components/gree/gree.h +5 -1
  9. esphome/components/heatpumpir/climate.py +6 -5
  10. esphome/components/heatpumpir/heatpumpir.cpp +5 -0
  11. esphome/components/heatpumpir/heatpumpir.h +5 -0
  12. esphome/components/http_request/http_request_arduino.cpp +7 -2
  13. esphome/components/ltr390/ltr390.cpp +44 -29
  14. esphome/components/ltr390/ltr390.h +9 -5
  15. esphome/components/ltr390/sensor.py +35 -5
  16. esphome/components/mitsubishi/mitsubishi.cpp +1 -0
  17. esphome/components/pmsa003i/pmsa003i.cpp +9 -0
  18. esphome/components/restart/button/__init__.py +2 -0
  19. esphome/components/voice_assistant/voice_assistant.cpp +3 -1
  20. esphome/components/web_server/server_index_v2.h +42 -41
  21. esphome/components/web_server/server_index_v3.h +368 -367
  22. esphome/const.py +1 -1
  23. esphome/core/helpers.cpp +1 -1
  24. {esphome-2024.7.0b1.dist-info → esphome-2024.7.0b2.dist-info}/METADATA +1 -1
  25. {esphome-2024.7.0b1.dist-info → esphome-2024.7.0b2.dist-info}/RECORD +29 -29
  26. {esphome-2024.7.0b1.dist-info → esphome-2024.7.0b2.dist-info}/LICENSE +0 -0
  27. {esphome-2024.7.0b1.dist-info → esphome-2024.7.0b2.dist-info}/WHEEL +0 -0
  28. {esphome-2024.7.0b1.dist-info → esphome-2024.7.0b2.dist-info}/entry_points.txt +0 -0
  29. {esphome-2024.7.0b1.dist-info → esphome-2024.7.0b2.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, " [x] Supports current temperature");
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, " [x] Supports current humidity");
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; }
@@ -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
 
@@ -394,7 +394,7 @@ void EthernetComponent::got_ip_event_handler(void *arg, esp_event_base_t event_b
394
394
  const esp_netif_ip_info_t *ip_info = &event->ip_info;
395
395
  ESP_LOGV(TAG, "[Ethernet event] ETH Got IP " IPSTR, IP2STR(&ip_info->ip));
396
396
  global_eth_component->got_ipv4_address_ = true;
397
- #if USE_NETWORK_IPV6
397
+ #if USE_NETWORK_IPV6 && (USE_NETWORK_MIN_IPV6_ADDR_COUNT > 0)
398
398
  global_eth_component->connected_ = global_eth_component->ipv6_count_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT;
399
399
  #else
400
400
  global_eth_component->connected_ = true;
@@ -407,8 +407,12 @@ void EthernetComponent::got_ip6_event_handler(void *arg, esp_event_base_t event_
407
407
  ip_event_got_ip6_t *event = (ip_event_got_ip6_t *) event_data;
408
408
  ESP_LOGV(TAG, "[Ethernet event] ETH Got IPv6: " IPV6STR, IPV62STR(event->ip6_info.ip));
409
409
  global_eth_component->ipv6_count_ += 1;
410
+ #if (USE_NETWORK_MIN_IPV6_ADDR_COUNT > 0)
410
411
  global_eth_component->connected_ =
411
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
412
416
  }
413
417
  #endif /* USE_NETWORK_IPV6 */
414
418
 
@@ -16,6 +16,7 @@ MODELS = {
16
16
  "yan": Model.GREE_YAN,
17
17
  "yaa": Model.GREE_YAA,
18
18
  "yac": Model.GREE_YAC,
19
+ "yac1fb9": Model.GREE_YAC1FB9,
19
20
  }
20
21
 
21
22
  CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
@@ -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
- data->space(GREE_HEADER_SPACE);
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
- data->space(GREE_MESSAGE_SPACE);
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
@@ -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:
@@ -8,7 +8,6 @@ from esphome.const import (
8
8
  CONF_PROTOCOL,
9
9
  CONF_VISUAL,
10
10
  )
11
- from esphome.core import CORE
12
11
 
13
12
  CODEOWNERS = ["@rob-deutsch"]
14
13
 
@@ -67,6 +66,11 @@ PROTOCOLS = {
67
66
  "carrier_qlima_2": Protocol.PROTOCOL_QLIMA_2,
68
67
  "samsung_aqv12msan": Protocol.PROTOCOL_SAMSUNG_AQV12MSAN,
69
68
  "zhjg01": Protocol.PROTOCOL_ZHJG01,
69
+ "airway": Protocol.PROTOCOL_AIRWAY,
70
+ "bgh_aud": Protocol.PROTOCOL_BGH_AUD,
71
+ "panasonic_altdke": Protocol.PROTOCOL_PANASONIC_ALTDKE,
72
+ "vaillantvai8": Protocol.PROTOCOL_VAILLANTVAI8,
73
+ "r51m": Protocol.PROTOCOL_R51M,
70
74
  }
71
75
 
72
76
  CONF_HORIZONTAL_DEFAULT = "horizontal_default"
@@ -122,7 +126,4 @@ def to_code(config):
122
126
  cg.add(var.set_max_temperature(config[CONF_MAX_TEMPERATURE]))
123
127
  cg.add(var.set_min_temperature(config[CONF_MIN_TEMPERATURE]))
124
128
 
125
- cg.add_library("tonia/HeatpumpIR", "1.0.26")
126
-
127
- if CORE.is_esp8266 or CORE.is_esp32:
128
- cg.add_library("crankyoldgit/IRremoteESP8266", "2.8.6")
129
+ cg.add_library("tonia/HeatpumpIR", "1.0.27")
@@ -61,6 +61,11 @@ const std::map<Protocol, std::function<HeatpumpIR *()>> PROTOCOL_CONSTRUCTOR_MAP
61
61
  {PROTOCOL_QLIMA_2, []() { return new Qlima2HeatpumpIR(); }}, // NOLINT
62
62
  {PROTOCOL_SAMSUNG_AQV12MSAN, []() { return new SamsungAQV12MSANHeatpumpIR(); }}, // NOLINT
63
63
  {PROTOCOL_ZHJG01, []() { return new ZHJG01HeatpumpIR(); }}, // NOLINT
64
+ {PROTOCOL_AIRWAY, []() { return new AIRWAYHeatpumpIR(); }}, // NOLINT
65
+ {PROTOCOL_BGH_AUD, []() { return new BGHHeatpumpIR(); }}, // NOLINT
66
+ {PROTOCOL_PANASONIC_ALTDKE, []() { return new PanasonicAltDKEHeatpumpIR(); }}, // NOLINT
67
+ {PROTOCOL_VAILLANTVAI8, []() { return new VaillantHeatpumpIR(); }}, // NOLINT
68
+ {PROTOCOL_R51M, []() { return new R51MHeatpumpIR(); }}, // NOLINT
64
69
  };
65
70
 
66
71
  void HeatpumpIRClimate::setup() {
@@ -61,6 +61,11 @@ enum Protocol {
61
61
  PROTOCOL_QLIMA_2,
62
62
  PROTOCOL_SAMSUNG_AQV12MSAN,
63
63
  PROTOCOL_ZHJG01,
64
+ PROTOCOL_AIRWAY,
65
+ PROTOCOL_BGH_AUD,
66
+ PROTOCOL_PANASONIC_ALTDKE,
67
+ PROTOCOL_VAILLANTVAI8,
68
+ PROTOCOL_R51M,
64
69
  };
65
70
 
66
71
  // Simple enum to represent horizontal directios
@@ -32,6 +32,13 @@ std::shared_ptr<HttpContainer> HttpRequestArduino::start(std::string url, std::s
32
32
 
33
33
  watchdog::WatchdogManager wdm(this->get_watchdog_timeout());
34
34
 
35
+ if (this->follow_redirects_) {
36
+ container->client_.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
37
+ container->client_.setRedirectLimit(this->redirect_limit_);
38
+ } else {
39
+ container->client_.setFollowRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS);
40
+ }
41
+
35
42
  #if defined(USE_ESP8266)
36
43
  std::unique_ptr<WiFiClient> stream_ptr;
37
44
  #ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
@@ -59,8 +66,6 @@ std::shared_ptr<HttpContainer> HttpRequestArduino::start(std::string url, std::s
59
66
  "in your YAML, or use HTTPS");
60
67
  }
61
68
  #endif // USE_ARDUINO_VERSION_CODE
62
-
63
- container->client_.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
64
69
  bool status = container->client_.begin(*stream_ptr, url.c_str());
65
70
 
66
71
  #elif defined(USE_RP2040)
@@ -19,6 +19,7 @@ static const uint8_t LTR390_MAIN_STATUS = 0x07;
19
19
 
20
20
  static const float GAINVALUES[5] = {1.0, 3.0, 6.0, 9.0, 18.0};
21
21
  static const float RESOLUTIONVALUE[6] = {4.0, 2.0, 1.0, 0.5, 0.25, 0.125};
22
+ static const uint8_t RESOLUTION_BITS[6] = {20, 19, 18, 17, 16, 13};
22
23
 
23
24
  // Request fastest measurement rate - will be slowed by device if conversion rate is slower.
24
25
  static const float RESOLUTION_SETTING[6] = {0x00, 0x10, 0x20, 0x30, 0x40, 0x50};
@@ -74,7 +75,7 @@ void LTR390Component::read_als_() {
74
75
  uint32_t als = *val;
75
76
 
76
77
  if (this->light_sensor_ != nullptr) {
77
- float lux = ((0.6 * als) / (GAINVALUES[this->gain_] * RESOLUTIONVALUE[this->res_])) * this->wfac_;
78
+ float lux = ((0.6 * als) / (GAINVALUES[this->gain_als_] * RESOLUTIONVALUE[this->res_als_])) * this->wfac_;
78
79
  this->light_sensor_->publish_state(lux);
79
80
  }
80
81
 
@@ -90,7 +91,7 @@ void LTR390Component::read_uvs_() {
90
91
  uint32_t uv = *val;
91
92
 
92
93
  if (this->uvi_sensor_ != nullptr) {
93
- this->uvi_sensor_->publish_state((uv / this->sensitivity_) * this->wfac_);
94
+ this->uvi_sensor_->publish_state((uv / this->sensitivity_uv_) * this->wfac_);
94
95
  }
95
96
 
96
97
  if (this->uv_sensor_ != nullptr) {
@@ -107,24 +108,38 @@ void LTR390Component::read_mode_(int mode_index) {
107
108
  ctrl[LTR390_CTRL_EN] = true;
108
109
  this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
109
110
 
111
+ uint32_t int_time{0};
112
+ // Set gain, resolution and measurement rate
113
+ switch (mode) {
114
+ case LTR390_MODE_ALS:
115
+ this->reg(LTR390_GAIN) = this->gain_als_;
116
+ this->reg(LTR390_MEAS_RATE) = RESOLUTION_SETTING[this->res_als_];
117
+ int_time = ((uint32_t) RESOLUTIONVALUE[this->res_als_]) * 100;
118
+ break;
119
+ case LTR390_MODE_UVS:
120
+ this->reg(LTR390_GAIN) = this->gain_uv_;
121
+ this->reg(LTR390_MEAS_RATE) = RESOLUTION_SETTING[this->res_uv_];
122
+ int_time = ((uint32_t) RESOLUTIONVALUE[this->res_uv_]) * 100;
123
+ break;
124
+ }
125
+
110
126
  // After the sensor integration time do the following
111
- this->set_timeout(((uint32_t) RESOLUTIONVALUE[this->res_]) * 100 + LTR390_WAKEUP_TIME + LTR390_SETTLE_TIME,
112
- [this, mode_index]() {
113
- // Read from the sensor
114
- std::get<1>(this->mode_funcs_[mode_index])();
115
-
116
- // If there are more modes to read then begin the next
117
- // otherwise stop
118
- if (mode_index + 1 < (int) this->mode_funcs_.size()) {
119
- this->read_mode_(mode_index + 1);
120
- } else {
121
- // put sensor in standby
122
- std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
123
- ctrl[LTR390_CTRL_EN] = false;
124
- this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
125
- this->reading_ = false;
126
- }
127
- });
127
+ this->set_timeout(int_time + LTR390_WAKEUP_TIME + LTR390_SETTLE_TIME, [this, mode_index]() {
128
+ // Read from the sensor
129
+ std::get<1>(this->mode_funcs_[mode_index])();
130
+
131
+ // If there are more modes to read then begin the next
132
+ // otherwise stop
133
+ if (mode_index + 1 < (int) this->mode_funcs_.size()) {
134
+ this->read_mode_(mode_index + 1);
135
+ } else {
136
+ // put sensor in standby
137
+ std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
138
+ ctrl[LTR390_CTRL_EN] = false;
139
+ this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
140
+ this->reading_ = false;
141
+ }
142
+ });
128
143
  }
129
144
 
130
145
  void LTR390Component::setup() {
@@ -151,16 +166,10 @@ void LTR390Component::setup() {
151
166
  return;
152
167
  }
153
168
 
154
- // Set gain
155
- this->reg(LTR390_GAIN) = gain_;
156
-
157
- // Set resolution and measurement rate
158
- this->reg(LTR390_MEAS_RATE) = RESOLUTION_SETTING[this->res_];
159
-
160
169
  // Set sensitivity by linearly scaling against known value in the datasheet
161
- float gain_scale = GAINVALUES[this->gain_] / GAIN_MAX;
162
- float intg_scale = (RESOLUTIONVALUE[this->res_] * 100) / INTG_MAX;
163
- this->sensitivity_ = SENSITIVITY_MAX * gain_scale * intg_scale;
170
+ float gain_scale_uv = GAINVALUES[this->gain_uv_] / GAIN_MAX;
171
+ float intg_scale_uv = (RESOLUTIONVALUE[this->res_uv_] * 100) / INTG_MAX;
172
+ this->sensitivity_uv_ = SENSITIVITY_MAX * gain_scale_uv * intg_scale_uv;
164
173
 
165
174
  // Set sensor read state
166
175
  this->reading_ = false;
@@ -176,7 +185,13 @@ void LTR390Component::setup() {
176
185
  }
177
186
  }
178
187
 
179
- void LTR390Component::dump_config() { LOG_I2C_DEVICE(this); }
188
+ void LTR390Component::dump_config() {
189
+ LOG_I2C_DEVICE(this);
190
+ ESP_LOGCONFIG(TAG, " ALS Gain: X%.0f", GAINVALUES[this->gain_als_]);
191
+ ESP_LOGCONFIG(TAG, " ALS Resolution: %u-bit", RESOLUTION_BITS[this->res_als_]);
192
+ ESP_LOGCONFIG(TAG, " UV Gain: X%.0f", GAINVALUES[this->gain_uv_]);
193
+ ESP_LOGCONFIG(TAG, " UV Resolution: %u-bit", RESOLUTION_BITS[this->res_uv_]);
194
+ }
180
195
 
181
196
  void LTR390Component::update() {
182
197
  if (!this->reading_ && !mode_funcs_.empty()) {
@@ -49,8 +49,10 @@ class LTR390Component : public PollingComponent, public i2c::I2CDevice {
49
49
  void dump_config() override;
50
50
  void update() override;
51
51
 
52
- void set_gain_value(LTR390GAIN gain) { this->gain_ = gain; }
53
- void set_res_value(LTR390RESOLUTION res) { this->res_ = res; }
52
+ void set_als_gain_value(LTR390GAIN gain) { this->gain_als_ = gain; }
53
+ void set_uv_gain_value(LTR390GAIN gain) { this->gain_uv_ = gain; }
54
+ void set_als_res_value(LTR390RESOLUTION res) { this->res_als_ = res; }
55
+ void set_uv_res_value(LTR390RESOLUTION res) { this->res_uv_ = res; }
54
56
  void set_wfac_value(float wfac) { this->wfac_ = wfac; }
55
57
 
56
58
  void set_light_sensor(sensor::Sensor *light_sensor) { this->light_sensor_ = light_sensor; }
@@ -71,9 +73,11 @@ class LTR390Component : public PollingComponent, public i2c::I2CDevice {
71
73
  // a list of modes and corresponding read functions
72
74
  std::vector<std::tuple<LTR390MODE, std::function<void()>>> mode_funcs_;
73
75
 
74
- LTR390GAIN gain_;
75
- LTR390RESOLUTION res_;
76
- float sensitivity_;
76
+ LTR390GAIN gain_als_;
77
+ LTR390GAIN gain_uv_;
78
+ LTR390RESOLUTION res_als_;
79
+ LTR390RESOLUTION res_uv_;
80
+ float sensitivity_uv_;
77
81
  float wfac_;
78
82
 
79
83
  sensor::Sensor *light_sensor_{nullptr};
@@ -13,7 +13,7 @@ from esphome.const import (
13
13
  UNIT_LUX,
14
14
  )
15
15
 
16
- CODEOWNERS = ["@sjtrny"]
16
+ CODEOWNERS = ["@sjtrny", "@latonita"]
17
17
  DEPENDENCIES = ["i2c"]
18
18
 
19
19
  ltr390_ns = cg.esphome_ns.namespace("ltr390")
@@ -76,8 +76,24 @@ CONFIG_SCHEMA = cv.All(
76
76
  accuracy_decimals=1,
77
77
  device_class=DEVICE_CLASS_EMPTY,
78
78
  ),
79
- cv.Optional(CONF_GAIN, default="X18"): cv.enum(GAIN_OPTIONS),
80
- cv.Optional(CONF_RESOLUTION, default=20): cv.enum(RES_OPTIONS),
79
+ cv.Optional(CONF_GAIN, default="X18"): cv.Any(
80
+ cv.enum(GAIN_OPTIONS),
81
+ cv.Schema(
82
+ {
83
+ cv.Required(CONF_AMBIENT_LIGHT): cv.enum(GAIN_OPTIONS),
84
+ cv.Required(CONF_UV): cv.enum(GAIN_OPTIONS),
85
+ }
86
+ ),
87
+ ),
88
+ cv.Optional(CONF_RESOLUTION, default=20): cv.Any(
89
+ cv.enum(RES_OPTIONS),
90
+ cv.Schema(
91
+ {
92
+ cv.Required(CONF_AMBIENT_LIGHT): cv.enum(RES_OPTIONS),
93
+ cv.Required(CONF_UV): cv.enum(RES_OPTIONS),
94
+ }
95
+ ),
96
+ ),
81
97
  cv.Optional(CONF_WINDOW_CORRECTION_FACTOR, default=1.0): cv.float_range(
82
98
  min=1.0
83
99
  ),
@@ -101,11 +117,25 @@ async def to_code(config):
101
117
  await cg.register_component(var, config)
102
118
  await i2c.register_i2c_device(var, config)
103
119
 
104
- cg.add(var.set_gain_value(config[CONF_GAIN]))
105
- cg.add(var.set_res_value(config[CONF_RESOLUTION]))
106
120
  cg.add(var.set_wfac_value(config[CONF_WINDOW_CORRECTION_FACTOR]))
107
121
 
108
122
  for key, funcName in TYPES.items():
109
123
  if key in config:
110
124
  sens = await sensor.new_sensor(config[key])
111
125
  cg.add(getattr(var, funcName)(sens))
126
+
127
+ gain_value = config[CONF_GAIN]
128
+ if isinstance(gain_value, dict):
129
+ cg.add(var.set_als_gain_value(gain_value[CONF_AMBIENT_LIGHT]))
130
+ cg.add(var.set_uv_gain_value(gain_value[CONF_UV]))
131
+ else:
132
+ cg.add(var.set_als_gain_value(gain_value))
133
+ cg.add(var.set_uv_gain_value(gain_value))
134
+
135
+ res_value = config[CONF_RESOLUTION]
136
+ if isinstance(res_value, dict):
137
+ cg.add(var.set_als_res_value(res_value[CONF_AMBIENT_LIGHT]))
138
+ cg.add(var.set_uv_res_value(res_value[CONF_UV]))
139
+ else:
140
+ cg.add(var.set_als_res_value(res_value))
141
+ cg.add(var.set_uv_res_value(res_value))
@@ -52,6 +52,7 @@ const uint8_t MITSUBISHI_BYTE16 = 0X00;
52
52
 
53
53
  climate::ClimateTraits MitsubishiClimate::traits() {
54
54
  auto traits = climate::ClimateTraits();
55
+ traits.set_supports_current_temperature(this->sensor_ != nullptr);
55
56
  traits.set_supports_action(false);
56
57
  traits.set_visual_min_temperature(MITSUBISHI_TEMP_MIN);
57
58
  traits.set_visual_max_temperature(MITSUBISHI_TEMP_MAX);
@@ -13,6 +13,15 @@ void PMSA003IComponent::setup() {
13
13
  PM25AQIData data;
14
14
  bool successful_read = this->read_data_(&data);
15
15
 
16
+ if (!successful_read) {
17
+ for (int i = 0; i < 3; i++) {
18
+ successful_read = this->read_data_(&data);
19
+ if (successful_read) {
20
+ break;
21
+ }
22
+ }
23
+ }
24
+
16
25
  if (!successful_read) {
17
26
  this->mark_failed();
18
27
  return;
@@ -5,6 +5,7 @@ from esphome.const import (
5
5
  CONF_ID,
6
6
  DEVICE_CLASS_RESTART,
7
7
  ENTITY_CATEGORY_CONFIG,
8
+ ICON_RESTART,
8
9
  )
9
10
 
10
11
  restart_ns = cg.esphome_ns.namespace("restart")
@@ -12,6 +13,7 @@ RestartButton = restart_ns.class_("RestartButton", button.Button, cg.Component)
12
13
 
13
14
  CONFIG_SCHEMA = button.button_schema(
14
15
  RestartButton,
16
+ icon=ICON_RESTART,
15
17
  device_class=DEVICE_CLASS_RESTART,
16
18
  entity_category=ENTITY_CATEGORY_CONFIG,
17
19
  ).extend(cv.COMPONENT_SCHEMA)
@@ -684,7 +684,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
684
684
  this->defer([this, text]() {
685
685
  this->tts_start_trigger_->trigger(text);
686
686
  #ifdef USE_SPEAKER
687
- this->speaker_->start();
687
+ if (this->speaker_ != nullptr) {
688
+ this->speaker_->start();
689
+ }
688
690
  #endif
689
691
  });
690
692
  break;