Merge remote-tracking branch 'upstream/binary-sensor-filters-drop-component' into integration

This commit is contained in:
J. Nick Koston
2026-04-29 11:08:17 -05:00
11 changed files with 46 additions and 56 deletions
+1 -5
View File
@@ -14,11 +14,7 @@ class AQICalculator : public AbstractAQICalculator {
uint16_t get_aqi(float pm2_5_value, float pm10_0_value) override {
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
float aqi = std::max(pm2_5_index, pm10_0_index);
if (aqi < 0.0f) {
aqi = 0.0f;
}
float aqi = std::max({pm2_5_index, pm10_0_index, 0.0f});
return static_cast<uint16_t>(std::lround(aqi));
}
+1 -5
View File
@@ -12,11 +12,7 @@ class CAQICalculator : public AbstractAQICalculator {
uint16_t get_aqi(float pm2_5_value, float pm10_0_value) override {
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
float aqi = std::max(pm2_5_index, pm10_0_index);
if (aqi < 0.0f) {
aqi = 0.0f;
}
float aqi = std::max({pm2_5_index, pm10_0_index, 0.0f});
return static_cast<uint16_t>(std::lround(aqi));
}
+20 -28
View File
@@ -85,7 +85,7 @@ void HonClimate::set_horizontal_airflow(hon_protocol::HorizontalSwingMode direct
this->force_send_control_ = true;
}
std::string HonClimate::get_cleaning_status_text() const {
const char *HonClimate::get_cleaning_status_text() const {
switch (this->cleaning_status_) {
case CleaningState::SELF_CLEAN:
return "Self clean";
@@ -134,29 +134,22 @@ haier_protocol::HandlerError HonClimate::get_device_version_answer_handler_(haie
}
// All OK
hon_protocol::DeviceVersionAnswer *answr = (hon_protocol::DeviceVersionAnswer *) data;
char tmp[9];
tmp[8] = 0;
strncpy(tmp, answr->protocol_version, 8);
this->hvac_hardware_info_ = HardwareInfo();
this->hvac_hardware_info_.value().protocol_version_ = std::string(tmp);
strncpy(tmp, answr->software_version, 8);
this->hvac_hardware_info_.value().software_version_ = std::string(tmp);
strncpy(tmp, answr->hardware_version, 8);
this->hvac_hardware_info_.value().hardware_version_ = std::string(tmp);
strncpy(tmp, answr->device_name, 8);
this->hvac_hardware_info_.value().device_name_ = std::string(tmp);
HardwareInfo info{}; // zero-init guarantees null-termination
strncpy(info.protocol_version_, answr->protocol_version, HARDWARE_INFO_STR_SIZE - 1);
strncpy(info.software_version_, answr->software_version, HARDWARE_INFO_STR_SIZE - 1);
strncpy(info.hardware_version_, answr->hardware_version, HARDWARE_INFO_STR_SIZE - 1);
strncpy(info.device_name_, answr->device_name, HARDWARE_INFO_STR_SIZE - 1);
info.functions_[0] = (answr->functions[1] & 0x01) != 0; // interactive mode support
info.functions_[1] = (answr->functions[1] & 0x02) != 0; // controller-device mode support
info.functions_[2] = (answr->functions[1] & 0x04) != 0; // crc support
info.functions_[3] = (answr->functions[1] & 0x08) != 0; // multiple AC support
info.functions_[4] = (answr->functions[1] & 0x20) != 0; // roles support
this->use_crc_ = info.functions_[2];
#ifdef USE_TEXT_SENSOR
this->update_sub_text_sensor_(SubTextSensorType::APPLIANCE_NAME, this->hvac_hardware_info_.value().device_name_);
this->update_sub_text_sensor_(SubTextSensorType::PROTOCOL_VERSION,
this->hvac_hardware_info_.value().protocol_version_);
this->update_sub_text_sensor_(SubTextSensorType::APPLIANCE_NAME, info.device_name_);
this->update_sub_text_sensor_(SubTextSensorType::PROTOCOL_VERSION, info.protocol_version_);
#endif
this->hvac_hardware_info_.value().functions_[0] = (answr->functions[1] & 0x01) != 0; // interactive mode support
this->hvac_hardware_info_.value().functions_[1] =
(answr->functions[1] & 0x02) != 0; // controller-device mode support
this->hvac_hardware_info_.value().functions_[2] = (answr->functions[1] & 0x04) != 0; // crc support
this->hvac_hardware_info_.value().functions_[3] = (answr->functions[1] & 0x08) != 0; // multiple AC support
this->hvac_hardware_info_.value().functions_[4] = (answr->functions[1] & 0x20) != 0; // roles support
this->use_crc_ = this->hvac_hardware_info_.value().functions_[2];
this->hvac_hardware_info_ = info;
this->set_phase(ProtocolPhases::SENDING_INIT_2);
return result;
} else {
@@ -347,10 +340,9 @@ void HonClimate::dump_config() {
" Device software version: %s\n"
" Device hardware version: %s\n"
" Device name: %s",
this->hvac_hardware_info_.value().protocol_version_.c_str(),
this->hvac_hardware_info_.value().software_version_.c_str(),
this->hvac_hardware_info_.value().hardware_version_.c_str(),
this->hvac_hardware_info_.value().device_name_.c_str());
this->hvac_hardware_info_.value().protocol_version_,
this->hvac_hardware_info_.value().software_version_,
this->hvac_hardware_info_.value().hardware_version_, this->hvac_hardware_info_.value().device_name_);
ESP_LOGCONFIG(TAG, " Device features:%s%s%s%s%s",
(this->hvac_hardware_info_.value().functions_[0] ? " interactive" : ""),
(this->hvac_hardware_info_.value().functions_[1] ? " controller-device" : ""),
@@ -460,7 +452,7 @@ void HonClimate::process_phase(std::chrono::steady_clock::time_point now) {
if (this->action_request_.has_value()) {
if (this->action_request_.value().message.has_value()) {
this->send_message_(this->action_request_.value().message.value(), this->use_crc_);
this->action_request_.value().message.reset();
this->action_request_.value().message.reset(); // NOLINT(bugprone-unchecked-optional-access)
} else {
// Message already sent, reseting request and return to idle
this->action_request_.reset();
@@ -796,7 +788,7 @@ void HonClimate::set_sub_text_sensor(SubTextSensorType type, text_sensor::TextSe
}
}
void HonClimate::update_sub_text_sensor_(SubTextSensorType type, const std::string &value) {
void HonClimate::update_sub_text_sensor_(SubTextSensorType type, const char *value) {
size_t index = (size_t) type;
if (this->sub_text_sensors_[index] != nullptr)
this->sub_text_sensors_[index]->publish_state(value);
+7 -6
View File
@@ -90,7 +90,7 @@ class HonClimate : public HaierClimateBase {
void set_sub_text_sensor(SubTextSensorType type, text_sensor::TextSensor *sens);
protected:
void update_sub_text_sensor_(SubTextSensorType type, const std::string &value);
void update_sub_text_sensor_(SubTextSensorType type, const char *value);
text_sensor::TextSensor *sub_text_sensors_[(size_t) SubTextSensorType::SUB_TEXT_SENSOR_TYPE_COUNT]{nullptr};
#endif
#ifdef USE_SWITCH
@@ -116,7 +116,7 @@ class HonClimate : public HaierClimateBase {
void set_vertical_airflow(hon_protocol::VerticalSwingMode direction);
esphome::optional<hon_protocol::HorizontalSwingMode> get_horizontal_airflow() const;
void set_horizontal_airflow(hon_protocol::HorizontalSwingMode direction);
std::string get_cleaning_status_text() const;
const char *get_cleaning_status_text() const;
CleaningState get_cleaning_status() const;
void start_self_cleaning();
void start_steri_cleaning();
@@ -166,11 +166,12 @@ class HonClimate : public HaierClimateBase {
void fill_control_messages_queue_();
void clear_control_messages_queue_();
static constexpr size_t HARDWARE_INFO_STR_SIZE = 9;
struct HardwareInfo {
std::string protocol_version_;
std::string software_version_;
std::string hardware_version_;
std::string device_name_;
char protocol_version_[HARDWARE_INFO_STR_SIZE];
char software_version_[HARDWARE_INFO_STR_SIZE];
char hardware_version_[HARDWARE_INFO_STR_SIZE];
char device_name_[HARDWARE_INFO_STR_SIZE];
bool functions_[5];
};
@@ -191,7 +191,7 @@ void Smartair2Climate::process_phase(std::chrono::steady_clock::time_point now)
if (this->action_request_.has_value()) {
if (this->action_request_.value().message.has_value()) {
this->send_message_(this->action_request_.value().message.value(), this->use_crc_);
this->action_request_.value().message.reset();
this->action_request_.value().message.reset(); // NOLINT(bugprone-unchecked-optional-access)
} else {
// Message already sent, reseting request and return to idle
this->action_request_.reset();
@@ -139,12 +139,12 @@ void KamstrupKMPComponent::clear_uart_rx_buffer_() {
void KamstrupKMPComponent::read_command_(uint16_t command) {
uint8_t buffer[20] = {0};
int buffer_len = 0;
size_t buffer_len = 0;
int data;
int timeout = 250; // ms
// Read the data from the UART
while (timeout > 0 && buffer_len < static_cast<int>(sizeof(buffer))) {
while (timeout > 0 && buffer_len < sizeof(buffer)) {
if (this->available()) {
data = this->read();
if (data > -1) {
@@ -183,7 +183,7 @@ void KamstrupKMPComponent::read_command_(uint16_t command) {
// Decode
uint8_t msg[20] = {0};
int msg_len = 0;
for (int i = 1; i < buffer_len - 1; i++) {
for (size_t i = 1; i < buffer_len - 1; i++) {
if (buffer[i] == 0x1B) {
msg[msg_len++] = buffer[i + 1] ^ 0xFF;
i++;
@@ -588,6 +588,7 @@ void MixerSpeaker::mix_audio_samples(const int16_t *primary_buffer, audio::Audio
}
}
// NOLINTBEGIN(bugprone-unchecked-optional-access) -- audio_stream_info_ always set before this task is created
void MixerSpeaker::audio_mixer_task(void *params) {
MixerSpeaker *this_mixer = static_cast<MixerSpeaker *>(params);
@@ -764,6 +765,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
vTaskSuspend(nullptr); // Suspend this task indefinitely until the loop method deletes it
}
// NOLINTEND(bugprone-unchecked-optional-access)
} // namespace esphome::mixer_speaker
+1 -1
View File
@@ -275,7 +275,7 @@ static Ras2819tSecondPacketCodes get_ras_2819t_second_packet_codes(climate::Clim
*/
static uint8_t get_ras_2819t_temp_code(float temperature) {
int temp_index = static_cast<int>(temperature) - 18;
if (temp_index < 0 || temp_index >= static_cast<int>(sizeof(RAS_2819T_TEMP_CODES))) {
if (temp_index < 0 || static_cast<size_t>(temp_index) >= sizeof(RAS_2819T_TEMP_CODES)) {
ESP_LOGW(TAG, "Temperature %.1f°C out of range [18-30°C], defaulting to 24°C", temperature);
return 0x40; // Default to 24°C
}
+3 -2
View File
@@ -60,8 +60,9 @@ struct SchedulerNameLog {
return buffer;
} else { // SELF_POINTER
// static_name carries the void* key for SELF_POINTER (pointer-width union slot).
// Cast to const void* — %p requires a void* argument.
ESPHOME_snprintf_P(buffer, sizeof(buffer), ESPHOME_PSTR("self:%p"), static_cast<const void *>(static_name));
// %p is specified as void* (not const void*), so strip const for the varargs call.
ESPHOME_snprintf_P(buffer, sizeof(buffer), ESPHOME_PSTR("self:%p"),
const_cast<void *>(static_cast<const void *>(static_name)));
return buffer;
}
}
+2 -1
View File
@@ -146,7 +146,8 @@ class Scheduler {
}
// Name storage type discriminator for SchedulerItem
// Used to distinguish between static strings, hashed strings, numeric IDs, and internal numeric IDs
// Used to distinguish between static strings, hashed strings, numeric IDs, internal numeric IDs,
// and self-keyed pointers (caller-supplied `void *`, typically `this`).
enum class NameType : uint8_t {
STATIC_STRING = 0, // const char* pointer to static/flash storage
HASHED_STRING = 1, // uint32_t FNV-1a hash of a runtime string
@@ -1,9 +1,10 @@
"""Test the self-keyed scheduler API.
Verifies that `Scheduler::set_timeout(void *, ...)` / `set_interval(void *, ...)` and the
matching `cancel_*(void *)` overloads behave correctly: callbacks fire, distinct keys
don't collide, self-keyed and component-keyed namespaces are independent, and
re-registering the same key replaces the existing timer.
Verifies that `Scheduler::set_timeout(const void *, ...)` /
`set_interval(const void *, ...)` and the matching `cancel_*(const void *)`
overloads behave correctly: callbacks fire, distinct keys don't collide,
self-keyed and component-keyed namespaces are independent, and re-registering
the same key replaces the existing timer.
"""
import asyncio