mirror of
https://github.com/esphome/esphome.git
synced 2026-09-16 17:48:40 +00:00
Merge remote-tracking branch 'upstream/dev' into integration
This commit is contained in:
@@ -1025,6 +1025,13 @@ message CameraImageRequest {
|
||||
bool stream = 2;
|
||||
}
|
||||
|
||||
// ==================== TEMPERATURE UNIT ====================
|
||||
enum TemperatureUnit {
|
||||
TEMPERATURE_UNIT_CELSIUS = 0;
|
||||
TEMPERATURE_UNIT_FAHRENHEIT = 1;
|
||||
TEMPERATURE_UNIT_KELVIN = 2;
|
||||
}
|
||||
|
||||
// ==================== CLIMATE ====================
|
||||
enum ClimateMode {
|
||||
CLIMATE_MODE_OFF = 0;
|
||||
@@ -1110,6 +1117,7 @@ message ListEntitiesClimateResponse {
|
||||
float visual_max_humidity = 25;
|
||||
uint32 device_id = 26 [(field_ifdef) = "USE_DEVICES"];
|
||||
uint32 feature_flags = 27;
|
||||
TemperatureUnit temperature_unit = 28;
|
||||
}
|
||||
message ClimateStateResponse {
|
||||
option (id) = 47;
|
||||
@@ -1203,6 +1211,7 @@ message ListEntitiesWaterHeaterResponse {
|
||||
repeated WaterHeaterMode supported_modes = 11 [(container_pointer_no_template) = "water_heater::WaterHeaterModeMask"];
|
||||
// Bitmask of WaterHeaterFeature flags
|
||||
uint32 supported_features = 12;
|
||||
TemperatureUnit temperature_unit = 13;
|
||||
}
|
||||
|
||||
message WaterHeaterStateResponse {
|
||||
|
||||
@@ -1435,6 +1435,7 @@ uint8_t *ListEntitiesClimateResponse::encode(ProtoWriteBuffer &buffer PROTO_ENCO
|
||||
ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 26, this->device_id);
|
||||
#endif
|
||||
ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 27, this->feature_flags);
|
||||
ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 28, static_cast<uint32_t>(this->temperature_unit));
|
||||
return pos;
|
||||
}
|
||||
uint32_t ListEntitiesClimateResponse::calculate_size() const {
|
||||
@@ -1484,6 +1485,7 @@ uint32_t ListEntitiesClimateResponse::calculate_size() const {
|
||||
size += ProtoSize::calc_uint32(2, this->device_id);
|
||||
#endif
|
||||
size += ProtoSize::calc_uint32(2, this->feature_flags);
|
||||
size += this->temperature_unit ? 3 : 0;
|
||||
return size;
|
||||
}
|
||||
uint8_t *ClimateStateResponse::encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const {
|
||||
@@ -1641,6 +1643,7 @@ uint8_t *ListEntitiesWaterHeaterResponse::encode(ProtoWriteBuffer &buffer PROTO_
|
||||
ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 11, static_cast<uint32_t>(it), true);
|
||||
}
|
||||
ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 12, this->supported_features);
|
||||
ProtoEncode::encode_uint32(pos PROTO_ENCODE_DEBUG_ARG, 13, static_cast<uint32_t>(this->temperature_unit));
|
||||
return pos;
|
||||
}
|
||||
uint32_t ListEntitiesWaterHeaterResponse::calculate_size() const {
|
||||
@@ -1663,6 +1666,7 @@ uint32_t ListEntitiesWaterHeaterResponse::calculate_size() const {
|
||||
size += this->supported_modes->size() * 2;
|
||||
}
|
||||
size += ProtoSize::calc_uint32(1, this->supported_features);
|
||||
size += this->temperature_unit ? 2 : 0;
|
||||
return size;
|
||||
}
|
||||
uint8_t *WaterHeaterStateResponse::encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const {
|
||||
|
||||
@@ -92,6 +92,11 @@ enum SupportsResponseType : uint32_t {
|
||||
SUPPORTS_RESPONSE_STATUS = 100,
|
||||
};
|
||||
#endif
|
||||
enum TemperatureUnit : uint32_t {
|
||||
TEMPERATURE_UNIT_CELSIUS = 0,
|
||||
TEMPERATURE_UNIT_FAHRENHEIT = 1,
|
||||
TEMPERATURE_UNIT_KELVIN = 2,
|
||||
};
|
||||
#ifdef USE_CLIMATE
|
||||
enum ClimateMode : uint32_t {
|
||||
CLIMATE_MODE_OFF = 0,
|
||||
@@ -1371,7 +1376,7 @@ class CameraImageRequest final : public ProtoDecodableMessage {
|
||||
class ListEntitiesClimateResponse final : public InfoResponseProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 46;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 150;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 153;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const LogString *message_name() const override { return LOG_STR("list_entities_climate_response"); }
|
||||
#endif
|
||||
@@ -1393,6 +1398,7 @@ class ListEntitiesClimateResponse final : public InfoResponseProtoMessage {
|
||||
float visual_min_humidity{0.0f};
|
||||
float visual_max_humidity{0.0f};
|
||||
uint32_t feature_flags{0};
|
||||
enums::TemperatureUnit temperature_unit{};
|
||||
uint8_t *encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const;
|
||||
uint32_t calculate_size() const;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
@@ -1470,7 +1476,7 @@ class ClimateCommandRequest final : public CommandProtoMessage {
|
||||
class ListEntitiesWaterHeaterResponse final : public InfoResponseProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 132;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 63;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 65;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const LogString *message_name() const override { return LOG_STR("list_entities_water_heater_response"); }
|
||||
#endif
|
||||
@@ -1479,6 +1485,7 @@ class ListEntitiesWaterHeaterResponse final : public InfoResponseProtoMessage {
|
||||
float target_temperature_step{0.0f};
|
||||
const water_heater::WaterHeaterModeMask *supported_modes{};
|
||||
uint32_t supported_features{0};
|
||||
enums::TemperatureUnit temperature_unit{};
|
||||
uint8_t *encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const;
|
||||
uint32_t calculate_size() const;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
|
||||
@@ -297,6 +297,18 @@ template<> const char *proto_enum_to_string<enums::SupportsResponseType>(enums::
|
||||
}
|
||||
}
|
||||
#endif
|
||||
template<> const char *proto_enum_to_string<enums::TemperatureUnit>(enums::TemperatureUnit value) {
|
||||
switch (value) {
|
||||
case enums::TEMPERATURE_UNIT_CELSIUS:
|
||||
return ESPHOME_PSTR("TEMPERATURE_UNIT_CELSIUS");
|
||||
case enums::TEMPERATURE_UNIT_FAHRENHEIT:
|
||||
return ESPHOME_PSTR("TEMPERATURE_UNIT_FAHRENHEIT");
|
||||
case enums::TEMPERATURE_UNIT_KELVIN:
|
||||
return ESPHOME_PSTR("TEMPERATURE_UNIT_KELVIN");
|
||||
default:
|
||||
return ESPHOME_PSTR("UNKNOWN");
|
||||
}
|
||||
}
|
||||
#ifdef USE_CLIMATE
|
||||
template<> const char *proto_enum_to_string<enums::ClimateMode>(enums::ClimateMode value) {
|
||||
switch (value) {
|
||||
@@ -1538,6 +1550,7 @@ const char *ListEntitiesClimateResponse::dump_to(DumpBuffer &out) const {
|
||||
dump_field(out, ESPHOME_PSTR("device_id"), this->device_id);
|
||||
#endif
|
||||
dump_field(out, ESPHOME_PSTR("feature_flags"), this->feature_flags);
|
||||
dump_field(out, ESPHOME_PSTR("temperature_unit"), static_cast<enums::TemperatureUnit>(this->temperature_unit));
|
||||
return out.c_str();
|
||||
}
|
||||
const char *ClimateStateResponse::dump_to(DumpBuffer &out) const {
|
||||
@@ -1611,6 +1624,7 @@ const char *ListEntitiesWaterHeaterResponse::dump_to(DumpBuffer &out) const {
|
||||
dump_field(out, ESPHOME_PSTR("supported_modes"), static_cast<enums::WaterHeaterMode>(it), 4);
|
||||
}
|
||||
dump_field(out, ESPHOME_PSTR("supported_features"), this->supported_features);
|
||||
dump_field(out, ESPHOME_PSTR("temperature_unit"), static_cast<enums::TemperatureUnit>(this->temperature_unit));
|
||||
return out.c_str();
|
||||
}
|
||||
const char *WaterHeaterStateResponse::dump_to(DumpBuffer &out) const {
|
||||
|
||||
@@ -352,7 +352,7 @@ void MitsubishiCN105::set_target_temperature(float target_temperature) {
|
||||
ESP_LOGD(TAG, "Setting temperature out-of-range: %.1f", target_temperature);
|
||||
return;
|
||||
}
|
||||
this->status_.target_temperature = std::round(target_temperature);
|
||||
this->status_.target_temperature = target_temperature;
|
||||
this->pending_updates_.set(UpdateFlag::TEMPERATURE);
|
||||
}
|
||||
|
||||
@@ -387,9 +387,9 @@ void MitsubishiCN105::apply_settings_() {
|
||||
if (this->pending_updates_.has(UpdateFlag::TEMPERATURE)) {
|
||||
payload[1] |= 0x04;
|
||||
if (this->use_temperature_encoding_b_) {
|
||||
payload[14] = static_cast<uint8_t>(this->status_.target_temperature * 2.0f + 128.0f);
|
||||
payload[14] = static_cast<uint8_t>(std::round(this->status_.target_temperature * 2.0f) + 128);
|
||||
} else {
|
||||
payload[5] = static_cast<uint8_t>(TARGET_TEMPERATURE_ENC_A_OFFSET - this->status_.target_temperature);
|
||||
payload[5] = static_cast<uint8_t>(TARGET_TEMPERATURE_ENC_A_OFFSET - std::round(this->status_.target_temperature));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -837,7 +837,16 @@ def lint_no_std_to_string(fname, match):
|
||||
f"{highlight('std::to_string()')} (including unqualified {highlight('to_string()')}) "
|
||||
f"allocates heap memory. On long-running embedded devices, repeated heap allocations "
|
||||
f"fragment memory over time.\n"
|
||||
f"Please use {highlight('snprintf()')} with a stack buffer instead.\n"
|
||||
f"\n"
|
||||
f"For plain integer formatting, prefer the dedicated helpers in helpers.h over "
|
||||
f"{highlight('snprintf()')} — they avoid pulling in printf formatting code and are "
|
||||
f"smaller and faster:\n"
|
||||
f" int8_t: {highlight('int8_to_str(buf, val)')} (buf >= 5 bytes)\n"
|
||||
f" uint8_t/uint16_t/uint32_t: {highlight('uint32_to_str(buf, val)')} (buf = UINT32_MAX_STR_SIZE; smaller types auto-widen)\n"
|
||||
f"Example: {highlight('char buf[UINT32_MAX_STR_SIZE]; uint32_to_str(buf, value);')}\n"
|
||||
f"For sensor values, use {highlight('value_accuracy_to_buf()')} from helpers.h.\n"
|
||||
f"\n"
|
||||
f"Otherwise use {highlight('snprintf()')} with a stack buffer.\n"
|
||||
f"\n"
|
||||
f"Buffer sizes and format specifiers (sizes include sign and null terminator):\n"
|
||||
f" uint8_t: 4 chars - %u (or PRIu8)\n"
|
||||
@@ -851,7 +860,6 @@ def lint_no_std_to_string(fname, match):
|
||||
f" float/double: 24 chars - %.8g (15 digits + sign + decimal + e+XXX)\n"
|
||||
f" 317 chars - %f (for DBL_MAX: 309 int digits + decimal + 6 frac + sign)\n"
|
||||
f"\n"
|
||||
f"For sensor values, use value_accuracy_to_buf() from helpers.h.\n"
|
||||
f'Example: char buf[11]; snprintf(buf, sizeof(buf), "%" PRIu32, value);\n'
|
||||
f"(If strictly necessary, add `{highlight('// NOLINT')}` to the end of the line)"
|
||||
)
|
||||
|
||||
@@ -341,6 +341,17 @@ TEST(MitsubishiCN105Tests, ApplySettingsTemperatureEncodedB) {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x00, 0xC5));
|
||||
}
|
||||
|
||||
TEST(MitsubishiCN105Tests, ApplySettingsHalfDegreeTemperatureEncodedB) {
|
||||
auto ctx = TestContext{};
|
||||
|
||||
ctx.sut.use_temperature_encoding_b_ = true;
|
||||
ctx.sut.set_target_temperature(26.5f);
|
||||
ctx.sut.apply_settings();
|
||||
|
||||
EXPECT_THAT(ctx.uart.tx, ::testing::ElementsAre(0xFC, 0x41, 0x01, 0x30, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x00, 0xC4));
|
||||
}
|
||||
|
||||
TEST(MitsubishiCN105Tests, ApplyModeCool) {
|
||||
auto ctx = TestContext{};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user