1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[mqtt] Move switch string tables to PROGMEM_STRING_TABLE (#13802)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
J. Nick Koston
2026-02-06 19:30:05 +01:00
committed by GitHub
parent 41cecbfb0f
commit 86f91eed2f
6 changed files with 58 additions and 168 deletions

View File

@@ -13,31 +13,12 @@ static const char *const TAG = "mqtt.alarm_control_panel";
using namespace esphome::alarm_control_panel; using namespace esphome::alarm_control_panel;
// Alarm state MQTT strings indexed by AlarmControlPanelState enum (0-9)
PROGMEM_STRING_TABLE(AlarmMqttStateStrings, "disarmed", "armed_home", "armed_away", "armed_night", "armed_vacation",
"armed_custom_bypass", "pending", "arming", "disarming", "triggered", "unknown");
static ProgmemStr alarm_state_to_mqtt_str(AlarmControlPanelState state) { static ProgmemStr alarm_state_to_mqtt_str(AlarmControlPanelState state) {
switch (state) { return AlarmMqttStateStrings::get_progmem_str(static_cast<uint8_t>(state), AlarmMqttStateStrings::LAST_INDEX);
case ACP_STATE_DISARMED:
return ESPHOME_F("disarmed");
case ACP_STATE_ARMED_HOME:
return ESPHOME_F("armed_home");
case ACP_STATE_ARMED_AWAY:
return ESPHOME_F("armed_away");
case ACP_STATE_ARMED_NIGHT:
return ESPHOME_F("armed_night");
case ACP_STATE_ARMED_VACATION:
return ESPHOME_F("armed_vacation");
case ACP_STATE_ARMED_CUSTOM_BYPASS:
return ESPHOME_F("armed_custom_bypass");
case ACP_STATE_PENDING:
return ESPHOME_F("pending");
case ACP_STATE_ARMING:
return ESPHOME_F("arming");
case ACP_STATE_DISARMING:
return ESPHOME_F("disarming");
case ACP_STATE_TRIGGERED:
return ESPHOME_F("triggered");
default:
return ESPHOME_F("unknown");
}
} }
MQTTAlarmControlPanelComponent::MQTTAlarmControlPanelComponent(AlarmControlPanel *alarm_control_panel) MQTTAlarmControlPanelComponent::MQTTAlarmControlPanelComponent(AlarmControlPanel *alarm_control_panel)

View File

@@ -8,6 +8,7 @@
#include "esphome/core/entity_base.h" #include "esphome/core/entity_base.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/progmem.h"
#include "esphome/core/version.h" #include "esphome/core/version.h"
#ifdef USE_LOGGER #ifdef USE_LOGGER
#include "esphome/components/logger/logger.h" #include "esphome/components/logger/logger.h"
@@ -27,6 +28,11 @@ namespace esphome::mqtt {
static const char *const TAG = "mqtt"; static const char *const TAG = "mqtt";
// Disconnect reason strings indexed by MQTTClientDisconnectReason enum (0-8)
PROGMEM_STRING_TABLE(MQTTDisconnectReasonStrings, "TCP disconnected", "Unacceptable Protocol Version",
"Identifier Rejected", "Server Unavailable", "Malformed Credentials", "Not Authorized",
"Not Enough Space", "TLS Bad Fingerprint", "DNS Resolve Error", "Unknown");
MQTTClientComponent::MQTTClientComponent() { MQTTClientComponent::MQTTClientComponent() {
global_mqtt_client = this; global_mqtt_client = this;
char mac_addr[MAC_ADDRESS_BUFFER_SIZE]; char mac_addr[MAC_ADDRESS_BUFFER_SIZE];
@@ -348,36 +354,8 @@ void MQTTClientComponent::loop() {
mqtt_backend_.loop(); mqtt_backend_.loop();
if (this->disconnect_reason_.has_value()) { if (this->disconnect_reason_.has_value()) {
const LogString *reason_s; const LogString *reason_s = MQTTDisconnectReasonStrings::get_log_str(
switch (*this->disconnect_reason_) { static_cast<uint8_t>(*this->disconnect_reason_), MQTTDisconnectReasonStrings::LAST_INDEX);
case MQTTClientDisconnectReason::TCP_DISCONNECTED:
reason_s = LOG_STR("TCP disconnected");
break;
case MQTTClientDisconnectReason::MQTT_UNACCEPTABLE_PROTOCOL_VERSION:
reason_s = LOG_STR("Unacceptable Protocol Version");
break;
case MQTTClientDisconnectReason::MQTT_IDENTIFIER_REJECTED:
reason_s = LOG_STR("Identifier Rejected");
break;
case MQTTClientDisconnectReason::MQTT_SERVER_UNAVAILABLE:
reason_s = LOG_STR("Server Unavailable");
break;
case MQTTClientDisconnectReason::MQTT_MALFORMED_CREDENTIALS:
reason_s = LOG_STR("Malformed Credentials");
break;
case MQTTClientDisconnectReason::MQTT_NOT_AUTHORIZED:
reason_s = LOG_STR("Not Authorized");
break;
case MQTTClientDisconnectReason::ESP8266_NOT_ENOUGH_SPACE:
reason_s = LOG_STR("Not Enough Space");
break;
case MQTTClientDisconnectReason::TLS_BAD_FINGERPRINT:
reason_s = LOG_STR("TLS Bad Fingerprint");
break;
default:
reason_s = LOG_STR("Unknown");
break;
}
if (!network::is_connected()) { if (!network::is_connected()) {
reason_s = LOG_STR("WiFi disconnected"); reason_s = LOG_STR("WiFi disconnected");
} }

View File

@@ -13,109 +13,44 @@ static const char *const TAG = "mqtt.climate";
using namespace esphome::climate; using namespace esphome::climate;
// Climate mode MQTT strings indexed by ClimateMode enum (0-6): OFF, HEAT_COOL, COOL, HEAT, FAN_ONLY, DRY, AUTO
PROGMEM_STRING_TABLE(ClimateMqttModeStrings, "off", "heat_cool", "cool", "heat", "fan_only", "dry", "auto", "unknown");
static ProgmemStr climate_mode_to_mqtt_str(ClimateMode mode) { static ProgmemStr climate_mode_to_mqtt_str(ClimateMode mode) {
switch (mode) { return ClimateMqttModeStrings::get_progmem_str(static_cast<uint8_t>(mode), ClimateMqttModeStrings::LAST_INDEX);
case CLIMATE_MODE_OFF:
return ESPHOME_F("off");
case CLIMATE_MODE_HEAT_COOL:
return ESPHOME_F("heat_cool");
case CLIMATE_MODE_AUTO:
return ESPHOME_F("auto");
case CLIMATE_MODE_COOL:
return ESPHOME_F("cool");
case CLIMATE_MODE_HEAT:
return ESPHOME_F("heat");
case CLIMATE_MODE_FAN_ONLY:
return ESPHOME_F("fan_only");
case CLIMATE_MODE_DRY:
return ESPHOME_F("dry");
default:
return ESPHOME_F("unknown");
}
} }
// Climate action MQTT strings indexed by ClimateAction enum (0,2-6): OFF, (gap), COOLING, HEATING, IDLE, DRYING, FAN
PROGMEM_STRING_TABLE(ClimateMqttActionStrings, "off", "unknown", "cooling", "heating", "idle", "drying", "fan",
"unknown");
static ProgmemStr climate_action_to_mqtt_str(ClimateAction action) { static ProgmemStr climate_action_to_mqtt_str(ClimateAction action) {
switch (action) { return ClimateMqttActionStrings::get_progmem_str(static_cast<uint8_t>(action), ClimateMqttActionStrings::LAST_INDEX);
case CLIMATE_ACTION_OFF:
return ESPHOME_F("off");
case CLIMATE_ACTION_COOLING:
return ESPHOME_F("cooling");
case CLIMATE_ACTION_HEATING:
return ESPHOME_F("heating");
case CLIMATE_ACTION_IDLE:
return ESPHOME_F("idle");
case CLIMATE_ACTION_DRYING:
return ESPHOME_F("drying");
case CLIMATE_ACTION_FAN:
return ESPHOME_F("fan");
default:
return ESPHOME_F("unknown");
}
} }
// Climate fan mode MQTT strings indexed by ClimateFanMode enum (0-9)
PROGMEM_STRING_TABLE(ClimateMqttFanModeStrings, "on", "off", "auto", "low", "medium", "high", "middle", "focus",
"diffuse", "quiet", "unknown");
static ProgmemStr climate_fan_mode_to_mqtt_str(ClimateFanMode fan_mode) { static ProgmemStr climate_fan_mode_to_mqtt_str(ClimateFanMode fan_mode) {
switch (fan_mode) { return ClimateMqttFanModeStrings::get_progmem_str(static_cast<uint8_t>(fan_mode),
case CLIMATE_FAN_ON: ClimateMqttFanModeStrings::LAST_INDEX);
return ESPHOME_F("on");
case CLIMATE_FAN_OFF:
return ESPHOME_F("off");
case CLIMATE_FAN_AUTO:
return ESPHOME_F("auto");
case CLIMATE_FAN_LOW:
return ESPHOME_F("low");
case CLIMATE_FAN_MEDIUM:
return ESPHOME_F("medium");
case CLIMATE_FAN_HIGH:
return ESPHOME_F("high");
case CLIMATE_FAN_MIDDLE:
return ESPHOME_F("middle");
case CLIMATE_FAN_FOCUS:
return ESPHOME_F("focus");
case CLIMATE_FAN_DIFFUSE:
return ESPHOME_F("diffuse");
case CLIMATE_FAN_QUIET:
return ESPHOME_F("quiet");
default:
return ESPHOME_F("unknown");
}
} }
// Climate swing mode MQTT strings indexed by ClimateSwingMode enum (0-3): OFF, BOTH, VERTICAL, HORIZONTAL
PROGMEM_STRING_TABLE(ClimateMqttSwingModeStrings, "off", "both", "vertical", "horizontal", "unknown");
static ProgmemStr climate_swing_mode_to_mqtt_str(ClimateSwingMode swing_mode) { static ProgmemStr climate_swing_mode_to_mqtt_str(ClimateSwingMode swing_mode) {
switch (swing_mode) { return ClimateMqttSwingModeStrings::get_progmem_str(static_cast<uint8_t>(swing_mode),
case CLIMATE_SWING_OFF: ClimateMqttSwingModeStrings::LAST_INDEX);
return ESPHOME_F("off");
case CLIMATE_SWING_BOTH:
return ESPHOME_F("both");
case CLIMATE_SWING_VERTICAL:
return ESPHOME_F("vertical");
case CLIMATE_SWING_HORIZONTAL:
return ESPHOME_F("horizontal");
default:
return ESPHOME_F("unknown");
}
} }
// Climate preset MQTT strings indexed by ClimatePreset enum (0-7)
PROGMEM_STRING_TABLE(ClimateMqttPresetStrings, "none", "home", "away", "boost", "comfort", "eco", "sleep", "activity",
"unknown");
static ProgmemStr climate_preset_to_mqtt_str(ClimatePreset preset) { static ProgmemStr climate_preset_to_mqtt_str(ClimatePreset preset) {
switch (preset) { return ClimateMqttPresetStrings::get_progmem_str(static_cast<uint8_t>(preset), ClimateMqttPresetStrings::LAST_INDEX);
case CLIMATE_PRESET_NONE:
return ESPHOME_F("none");
case CLIMATE_PRESET_HOME:
return ESPHOME_F("home");
case CLIMATE_PRESET_ECO:
return ESPHOME_F("eco");
case CLIMATE_PRESET_AWAY:
return ESPHOME_F("away");
case CLIMATE_PRESET_BOOST:
return ESPHOME_F("boost");
case CLIMATE_PRESET_COMFORT:
return ESPHOME_F("comfort");
case CLIMATE_PRESET_SLEEP:
return ESPHOME_F("sleep");
case CLIMATE_PRESET_ACTIVITY:
return ESPHOME_F("activity");
default:
return ESPHOME_F("unknown");
}
} }
void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) { void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {

View File

@@ -14,6 +14,9 @@ namespace esphome::mqtt {
static const char *const TAG = "mqtt.component"; static const char *const TAG = "mqtt.component";
// Entity category MQTT strings indexed by EntityCategory enum: NONE(0) is skipped, CONFIG(1), DIAGNOSTIC(2)
PROGMEM_STRING_TABLE(EntityCategoryMqttStrings, "", "config", "diagnostic");
// Helper functions for building topic strings on stack // Helper functions for building topic strings on stack
inline char *append_str(char *p, const char *s, size_t len) { inline char *append_str(char *p, const char *s, size_t len) {
memcpy(p, s, len); memcpy(p, s, len);
@@ -213,13 +216,9 @@ bool MQTTComponent::send_discovery_() {
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks) // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
const auto entity_category = this->get_entity()->get_entity_category(); const auto entity_category = this->get_entity()->get_entity_category();
switch (entity_category) { if (entity_category != ENTITY_CATEGORY_NONE) {
case ENTITY_CATEGORY_NONE: root[MQTT_ENTITY_CATEGORY] = EntityCategoryMqttStrings::get_progmem_str(
break; static_cast<uint8_t>(entity_category), static_cast<uint8_t>(ENTITY_CATEGORY_CONFIG));
case ENTITY_CATEGORY_CONFIG:
case ENTITY_CATEGORY_DIAGNOSTIC:
root[MQTT_ENTITY_CATEGORY] = entity_category == ENTITY_CATEGORY_CONFIG ? "config" : "diagnostic";
break;
} }
if (config.state_topic) { if (config.state_topic) {

View File

@@ -1,5 +1,6 @@
#include "mqtt_number.h" #include "mqtt_number.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/progmem.h"
#include "mqtt_const.h" #include "mqtt_const.h"
@@ -12,6 +13,9 @@ static const char *const TAG = "mqtt.number";
using namespace esphome::number; using namespace esphome::number;
// Number mode MQTT strings indexed by NumberMode enum: AUTO(0) is skipped, BOX(1), SLIDER(2)
PROGMEM_STRING_TABLE(NumberMqttModeStrings, "", "box", "slider");
MQTTNumberComponent::MQTTNumberComponent(Number *number) : number_(number) {} MQTTNumberComponent::MQTTNumberComponent(Number *number) : number_(number) {}
void MQTTNumberComponent::setup() { void MQTTNumberComponent::setup() {
@@ -48,15 +52,10 @@ void MQTTNumberComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCon
if (!unit_of_measurement.empty()) { if (!unit_of_measurement.empty()) {
root[MQTT_UNIT_OF_MEASUREMENT] = unit_of_measurement; root[MQTT_UNIT_OF_MEASUREMENT] = unit_of_measurement;
} }
switch (this->number_->traits.get_mode()) { const auto mode = this->number_->traits.get_mode();
case NUMBER_MODE_AUTO: if (mode != NUMBER_MODE_AUTO) {
break; root[MQTT_MODE] =
case NUMBER_MODE_BOX: NumberMqttModeStrings::get_progmem_str(static_cast<uint8_t>(mode), static_cast<uint8_t>(NUMBER_MODE_BOX));
root[MQTT_MODE] = "box";
break;
case NUMBER_MODE_SLIDER:
root[MQTT_MODE] = "slider";
break;
} }
const auto device_class = this->number_->traits.get_device_class_ref(); const auto device_class = this->number_->traits.get_device_class_ref();
if (!device_class.empty()) { if (!device_class.empty()) {

View File

@@ -1,5 +1,6 @@
#include "mqtt_text.h" #include "mqtt_text.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/progmem.h"
#include "mqtt_const.h" #include "mqtt_const.h"
@@ -12,6 +13,9 @@ static const char *const TAG = "mqtt.text";
using namespace esphome::text; using namespace esphome::text;
// Text mode MQTT strings indexed by TextMode enum (0-1): TEXT, PASSWORD
PROGMEM_STRING_TABLE(TextMqttModeStrings, "text", "password");
MQTTTextComponent::MQTTTextComponent(Text *text) : text_(text) {} MQTTTextComponent::MQTTTextComponent(Text *text) : text_(text) {}
void MQTTTextComponent::setup() { void MQTTTextComponent::setup() {
@@ -34,14 +38,8 @@ const EntityBase *MQTTTextComponent::get_entity() const { return this->text_; }
void MQTTTextComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) { void MQTTTextComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
switch (this->text_->traits.get_mode()) { root[MQTT_MODE] = TextMqttModeStrings::get_progmem_str(static_cast<uint8_t>(this->text_->traits.get_mode()),
case TEXT_MODE_TEXT: static_cast<uint8_t>(TEXT_MODE_TEXT));
root[MQTT_MODE] = "text";
break;
case TEXT_MODE_PASSWORD:
root[MQTT_MODE] = "password";
break;
}
config.command_topic = true; config.command_topic = true;
} }