mirror of
https://github.com/esphome/esphome.git
synced 2026-02-10 03:27:36 -07:00
Compare commits
1 Commits
mqtt-custo
...
bmp_progme
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3b547b1b0 |
@@ -1 +1 @@
|
||||
37ec8d5a343c8d0a485fd2118cbdabcbccd7b9bca197e4a392be75087974dced
|
||||
069fa9526c52f7c580a9ec17c7678d12f142221387e9b561c18f95394d4629a3
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
*/
|
||||
|
||||
#include "bmp3xx_base.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
#include <cinttypes>
|
||||
|
||||
namespace esphome {
|
||||
@@ -26,46 +27,18 @@ static const LogString *chip_type_to_str(uint8_t chip_type) {
|
||||
}
|
||||
}
|
||||
|
||||
// Oversampling strings indexed by Oversampling enum (0-5): NONE, X2, X4, X8, X16, X32
|
||||
PROGMEM_STRING_TABLE(OversamplingStrings, "None", "2x", "4x", "8x", "16x", "32x", "");
|
||||
|
||||
static const LogString *oversampling_to_str(Oversampling oversampling) {
|
||||
switch (oversampling) {
|
||||
case Oversampling::OVERSAMPLING_NONE:
|
||||
return LOG_STR("None");
|
||||
case Oversampling::OVERSAMPLING_X2:
|
||||
return LOG_STR("2x");
|
||||
case Oversampling::OVERSAMPLING_X4:
|
||||
return LOG_STR("4x");
|
||||
case Oversampling::OVERSAMPLING_X8:
|
||||
return LOG_STR("8x");
|
||||
case Oversampling::OVERSAMPLING_X16:
|
||||
return LOG_STR("16x");
|
||||
case Oversampling::OVERSAMPLING_X32:
|
||||
return LOG_STR("32x");
|
||||
default:
|
||||
return LOG_STR("");
|
||||
}
|
||||
return OversamplingStrings::get_log_str(static_cast<uint8_t>(oversampling), OversamplingStrings::LAST_INDEX);
|
||||
}
|
||||
|
||||
// IIR filter strings indexed by IIRFilter enum (0-7): OFF, 2, 4, 8, 16, 32, 64, 128
|
||||
PROGMEM_STRING_TABLE(IIRFilterStrings, "OFF", "2x", "4x", "8x", "16x", "32x", "64x", "128x", "");
|
||||
|
||||
static const LogString *iir_filter_to_str(IIRFilter filter) {
|
||||
switch (filter) {
|
||||
case IIRFilter::IIR_FILTER_OFF:
|
||||
return LOG_STR("OFF");
|
||||
case IIRFilter::IIR_FILTER_2:
|
||||
return LOG_STR("2x");
|
||||
case IIRFilter::IIR_FILTER_4:
|
||||
return LOG_STR("4x");
|
||||
case IIRFilter::IIR_FILTER_8:
|
||||
return LOG_STR("8x");
|
||||
case IIRFilter::IIR_FILTER_16:
|
||||
return LOG_STR("16x");
|
||||
case IIRFilter::IIR_FILTER_32:
|
||||
return LOG_STR("32x");
|
||||
case IIRFilter::IIR_FILTER_64:
|
||||
return LOG_STR("64x");
|
||||
case IIRFilter::IIR_FILTER_128:
|
||||
return LOG_STR("128x");
|
||||
default:
|
||||
return LOG_STR("");
|
||||
}
|
||||
return IIRFilterStrings::get_log_str(static_cast<uint8_t>(filter), IIRFilterStrings::LAST_INDEX);
|
||||
}
|
||||
|
||||
void BMP3XXComponent::setup() {
|
||||
|
||||
@@ -11,57 +11,26 @@
|
||||
*/
|
||||
|
||||
#include "bmp581_base.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::bmp581_base {
|
||||
|
||||
static const char *const TAG = "bmp581";
|
||||
|
||||
// Oversampling strings indexed by Oversampling enum (0-7): NONE, X2, X4, X8, X16, X32, X64, X128
|
||||
PROGMEM_STRING_TABLE(OversamplingStrings, "None", "2x", "4x", "8x", "16x", "32x", "64x", "128x", "");
|
||||
|
||||
static const LogString *oversampling_to_str(Oversampling oversampling) {
|
||||
switch (oversampling) {
|
||||
case Oversampling::OVERSAMPLING_NONE:
|
||||
return LOG_STR("None");
|
||||
case Oversampling::OVERSAMPLING_X2:
|
||||
return LOG_STR("2x");
|
||||
case Oversampling::OVERSAMPLING_X4:
|
||||
return LOG_STR("4x");
|
||||
case Oversampling::OVERSAMPLING_X8:
|
||||
return LOG_STR("8x");
|
||||
case Oversampling::OVERSAMPLING_X16:
|
||||
return LOG_STR("16x");
|
||||
case Oversampling::OVERSAMPLING_X32:
|
||||
return LOG_STR("32x");
|
||||
case Oversampling::OVERSAMPLING_X64:
|
||||
return LOG_STR("64x");
|
||||
case Oversampling::OVERSAMPLING_X128:
|
||||
return LOG_STR("128x");
|
||||
default:
|
||||
return LOG_STR("");
|
||||
}
|
||||
return OversamplingStrings::get_log_str(static_cast<uint8_t>(oversampling), OversamplingStrings::LAST_INDEX);
|
||||
}
|
||||
|
||||
// IIR filter strings indexed by IIRFilter enum (0-7): OFF, 2, 4, 8, 16, 32, 64, 128
|
||||
PROGMEM_STRING_TABLE(IIRFilterStrings, "OFF", "2x", "4x", "8x", "16x", "32x", "64x", "128x", "");
|
||||
|
||||
static const LogString *iir_filter_to_str(IIRFilter filter) {
|
||||
switch (filter) {
|
||||
case IIRFilter::IIR_FILTER_OFF:
|
||||
return LOG_STR("OFF");
|
||||
case IIRFilter::IIR_FILTER_2:
|
||||
return LOG_STR("2x");
|
||||
case IIRFilter::IIR_FILTER_4:
|
||||
return LOG_STR("4x");
|
||||
case IIRFilter::IIR_FILTER_8:
|
||||
return LOG_STR("8x");
|
||||
case IIRFilter::IIR_FILTER_16:
|
||||
return LOG_STR("16x");
|
||||
case IIRFilter::IIR_FILTER_32:
|
||||
return LOG_STR("32x");
|
||||
case IIRFilter::IIR_FILTER_64:
|
||||
return LOG_STR("64x");
|
||||
case IIRFilter::IIR_FILTER_128:
|
||||
return LOG_STR("128x");
|
||||
default:
|
||||
return LOG_STR("");
|
||||
}
|
||||
return IIRFilterStrings::get_log_str(static_cast<uint8_t>(filter), IIRFilterStrings::LAST_INDEX);
|
||||
}
|
||||
|
||||
void BMP581Component::dump_config() {
|
||||
|
||||
@@ -66,7 +66,7 @@ async def to_code(config):
|
||||
cg.add_build_flag("-DDSMR_WATER_MBUS_ID=" + str(config[CONF_WATER_MBUS_ID]))
|
||||
|
||||
# DSMR Parser
|
||||
cg.add_library("esphome/dsmr_parser", "1.1.0")
|
||||
cg.add_library("esphome/dsmr_parser", "1.0.0")
|
||||
|
||||
# Crypto
|
||||
cg.add_library("polargoose/Crypto-no-arduino", "0.4.0")
|
||||
|
||||
@@ -718,6 +718,14 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
device_class=DEVICE_CLASS_POWER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional("fw_core_version"): sensor.sensor_schema(
|
||||
accuracy_decimals=3,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional("fw_module_version"): sensor.sensor_schema(
|
||||
accuracy_decimals=3,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@@ -26,9 +26,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
cv.Optional("sub_equipment_id"): text_sensor.text_sensor_schema(),
|
||||
cv.Optional("gas_delivered_text"): text_sensor.text_sensor_schema(),
|
||||
cv.Optional("fw_core_checksum"): text_sensor.text_sensor_schema(),
|
||||
cv.Optional("fw_core_version"): text_sensor.text_sensor_schema(),
|
||||
cv.Optional("fw_module_checksum"): text_sensor.text_sensor_schema(),
|
||||
cv.Optional("fw_module_version"): text_sensor.text_sensor_schema(),
|
||||
cv.Optional("telegram"): text_sensor.text_sensor_schema().extend(
|
||||
{cv.Optional(CONF_INTERNAL, default=True): cv.boolean}
|
||||
),
|
||||
|
||||
@@ -13,12 +13,31 @@ static const char *const TAG = "mqtt.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) {
|
||||
return AlarmMqttStateStrings::get_progmem_str(static_cast<uint8_t>(state), AlarmMqttStateStrings::LAST_INDEX);
|
||||
switch (state) {
|
||||
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)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
#include "esphome/core/version.h"
|
||||
#ifdef USE_LOGGER
|
||||
#include "esphome/components/logger/logger.h"
|
||||
@@ -28,11 +27,6 @@ namespace esphome::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() {
|
||||
global_mqtt_client = this;
|
||||
char mac_addr[MAC_ADDRESS_BUFFER_SIZE];
|
||||
@@ -354,8 +348,36 @@ void MQTTClientComponent::loop() {
|
||||
mqtt_backend_.loop();
|
||||
|
||||
if (this->disconnect_reason_.has_value()) {
|
||||
const LogString *reason_s = MQTTDisconnectReasonStrings::get_log_str(
|
||||
static_cast<uint8_t>(*this->disconnect_reason_), MQTTDisconnectReasonStrings::LAST_INDEX);
|
||||
const LogString *reason_s;
|
||||
switch (*this->disconnect_reason_) {
|
||||
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()) {
|
||||
reason_s = LOG_STR("WiFi disconnected");
|
||||
}
|
||||
|
||||
@@ -13,44 +13,109 @@ static const char *const TAG = "mqtt.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) {
|
||||
return ClimateMqttModeStrings::get_progmem_str(static_cast<uint8_t>(mode), ClimateMqttModeStrings::LAST_INDEX);
|
||||
switch (mode) {
|
||||
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) {
|
||||
return ClimateMqttActionStrings::get_progmem_str(static_cast<uint8_t>(action), ClimateMqttActionStrings::LAST_INDEX);
|
||||
switch (action) {
|
||||
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) {
|
||||
return ClimateMqttFanModeStrings::get_progmem_str(static_cast<uint8_t>(fan_mode),
|
||||
ClimateMqttFanModeStrings::LAST_INDEX);
|
||||
switch (fan_mode) {
|
||||
case CLIMATE_FAN_ON:
|
||||
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) {
|
||||
return ClimateMqttSwingModeStrings::get_progmem_str(static_cast<uint8_t>(swing_mode),
|
||||
ClimateMqttSwingModeStrings::LAST_INDEX);
|
||||
switch (swing_mode) {
|
||||
case CLIMATE_SWING_OFF:
|
||||
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) {
|
||||
return ClimateMqttPresetStrings::get_progmem_str(static_cast<uint8_t>(preset), ClimateMqttPresetStrings::LAST_INDEX);
|
||||
switch (preset) {
|
||||
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) {
|
||||
@@ -300,11 +365,9 @@ const EntityBase *MQTTClimateComponent::get_entity() const { return this->device
|
||||
|
||||
bool MQTTClimateComponent::publish_state_() {
|
||||
auto traits = this->device_->get_traits();
|
||||
// Reusable stack buffer for topic construction (avoids heap allocation per publish)
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
// mode
|
||||
bool success = true;
|
||||
if (!this->publish(this->get_mode_state_topic_to(topic_buf), climate_mode_to_mqtt_str(this->device_->mode)))
|
||||
if (!this->publish(this->get_mode_state_topic(), climate_mode_to_mqtt_str(this->device_->mode)))
|
||||
success = false;
|
||||
int8_t target_accuracy = traits.get_target_temperature_accuracy_decimals();
|
||||
int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
|
||||
@@ -313,70 +376,68 @@ bool MQTTClimateComponent::publish_state_() {
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE) &&
|
||||
!std::isnan(this->device_->current_temperature)) {
|
||||
len = value_accuracy_to_buf(payload, this->device_->current_temperature, current_accuracy);
|
||||
if (!this->publish(this->get_current_temperature_state_topic_to(topic_buf), payload, len))
|
||||
if (!this->publish(this->get_current_temperature_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE |
|
||||
climate::CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE)) {
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_temperature_low, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_low_state_topic_to(topic_buf), payload, len))
|
||||
if (!this->publish(this->get_target_temperature_low_state_topic(), payload, len))
|
||||
success = false;
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_temperature_high, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_high_state_topic_to(topic_buf), payload, len))
|
||||
if (!this->publish(this->get_target_temperature_high_state_topic(), payload, len))
|
||||
success = false;
|
||||
} else {
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_temperature, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_state_topic_to(topic_buf), payload, len))
|
||||
if (!this->publish(this->get_target_temperature_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_HUMIDITY) &&
|
||||
!std::isnan(this->device_->current_humidity)) {
|
||||
len = value_accuracy_to_buf(payload, this->device_->current_humidity, 0);
|
||||
if (!this->publish(this->get_current_humidity_state_topic_to(topic_buf), payload, len))
|
||||
if (!this->publish(this->get_current_humidity_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TARGET_HUMIDITY) &&
|
||||
!std::isnan(this->device_->target_humidity)) {
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_humidity, 0);
|
||||
if (!this->publish(this->get_target_humidity_state_topic_to(topic_buf), payload, len))
|
||||
if (!this->publish(this->get_target_humidity_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (traits.get_supports_presets() || !traits.get_supported_custom_presets().empty()) {
|
||||
if (this->device_->has_custom_preset()) {
|
||||
if (!this->publish(this->get_preset_state_topic_to(topic_buf), this->device_->get_custom_preset().c_str()))
|
||||
if (!this->publish(this->get_preset_state_topic(), this->device_->get_custom_preset()))
|
||||
success = false;
|
||||
} else if (this->device_->preset.has_value()) {
|
||||
if (!this->publish(this->get_preset_state_topic_to(topic_buf),
|
||||
climate_preset_to_mqtt_str(this->device_->preset.value())))
|
||||
if (!this->publish(this->get_preset_state_topic(), climate_preset_to_mqtt_str(this->device_->preset.value())))
|
||||
success = false;
|
||||
} else if (!this->publish(this->get_preset_state_topic_to(topic_buf), "")) {
|
||||
} else if (!this->publish(this->get_preset_state_topic(), "")) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_ACTION)) {
|
||||
if (!this->publish(this->get_action_state_topic_to(topic_buf), climate_action_to_mqtt_str(this->device_->action)))
|
||||
if (!this->publish(this->get_action_state_topic(), climate_action_to_mqtt_str(this->device_->action)))
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (traits.get_supports_fan_modes()) {
|
||||
if (this->device_->has_custom_fan_mode()) {
|
||||
if (!this->publish(this->get_fan_mode_state_topic_to(topic_buf), this->device_->get_custom_fan_mode().c_str()))
|
||||
if (!this->publish(this->get_fan_mode_state_topic(), this->device_->get_custom_fan_mode()))
|
||||
success = false;
|
||||
} else if (this->device_->fan_mode.has_value()) {
|
||||
if (!this->publish(this->get_fan_mode_state_topic_to(topic_buf),
|
||||
if (!this->publish(this->get_fan_mode_state_topic(),
|
||||
climate_fan_mode_to_mqtt_str(this->device_->fan_mode.value())))
|
||||
success = false;
|
||||
} else if (!this->publish(this->get_fan_mode_state_topic_to(topic_buf), "")) {
|
||||
} else if (!this->publish(this->get_fan_mode_state_topic(), "")) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (traits.get_supports_swing_modes()) {
|
||||
if (!this->publish(this->get_swing_mode_state_topic_to(topic_buf),
|
||||
climate_swing_mode_to_mqtt_str(this->device_->swing_mode)))
|
||||
if (!this->publish(this->get_swing_mode_state_topic(), climate_swing_mode_to_mqtt_str(this->device_->swing_mode)))
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,6 @@ namespace esphome::mqtt {
|
||||
|
||||
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
|
||||
inline char *append_str(char *p, const char *s, size_t len) {
|
||||
memcpy(p, s, len);
|
||||
@@ -216,9 +213,13 @@ bool MQTTComponent::send_discovery_() {
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
|
||||
const auto entity_category = this->get_entity()->get_entity_category();
|
||||
if (entity_category != ENTITY_CATEGORY_NONE) {
|
||||
root[MQTT_ENTITY_CATEGORY] = EntityCategoryMqttStrings::get_progmem_str(
|
||||
static_cast<uint8_t>(entity_category), static_cast<uint8_t>(ENTITY_CATEGORY_CONFIG));
|
||||
switch (entity_category) {
|
||||
case ENTITY_CATEGORY_NONE:
|
||||
break;
|
||||
case ENTITY_CATEGORY_CONFIG:
|
||||
case ENTITY_CATEGORY_DIAGNOSTIC:
|
||||
root[MQTT_ENTITY_CATEGORY] = entity_category == ENTITY_CATEGORY_CONFIG ? "config" : "diagnostic";
|
||||
break;
|
||||
}
|
||||
|
||||
if (config.state_topic) {
|
||||
|
||||
@@ -55,11 +55,6 @@ void log_mqtt_component(const char *tag, MQTTComponent *obj, bool state_topic, b
|
||||
\
|
||||
public: \
|
||||
void set_custom_##name##_##type##_topic(const std::string &topic) { this->custom_##name##_##type##_topic_ = topic; } \
|
||||
StringRef get_##name##_##type##_topic_to(std::span<char, MQTT_DEFAULT_TOPIC_MAX_LEN> buf) const { \
|
||||
if (!this->custom_##name##_##type##_topic_.empty()) \
|
||||
return StringRef(this->custom_##name##_##type##_topic_.data(), this->custom_##name##_##type##_topic_.size()); \
|
||||
return this->get_default_topic_for_to_(buf, #name "/" #type, sizeof(#name "/" #type) - 1); \
|
||||
} \
|
||||
std::string get_##name##_##type##_topic() const { \
|
||||
if (this->custom_##name##_##type##_topic_.empty()) \
|
||||
return this->get_default_topic_for_(#name "/" #type); \
|
||||
|
||||
@@ -112,19 +112,19 @@ bool MQTTCoverComponent::send_initial_state() { return this->publish_state(); }
|
||||
bool MQTTCoverComponent::publish_state() {
|
||||
auto traits = this->cover_->get_traits();
|
||||
bool success = true;
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (traits.get_supports_position()) {
|
||||
char pos[VALUE_ACCURACY_MAX_LEN];
|
||||
size_t len = value_accuracy_to_buf(pos, roundf(this->cover_->position * 100), 0);
|
||||
if (!this->publish(this->get_position_state_topic_to(topic_buf), pos, len))
|
||||
if (!this->publish(this->get_position_state_topic(), pos, len))
|
||||
success = false;
|
||||
}
|
||||
if (traits.get_supports_tilt()) {
|
||||
char pos[VALUE_ACCURACY_MAX_LEN];
|
||||
size_t len = value_accuracy_to_buf(pos, roundf(this->cover_->tilt * 100), 0);
|
||||
if (!this->publish(this->get_tilt_state_topic_to(topic_buf), pos, len))
|
||||
if (!this->publish(this->get_tilt_state_topic(), pos, len))
|
||||
success = false;
|
||||
}
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (!this->publish(this->get_state_topic_to_(topic_buf),
|
||||
cover_state_to_mqtt_str(this->cover_->current_operation, this->cover_->position,
|
||||
traits.get_supports_position())))
|
||||
|
||||
@@ -173,20 +173,19 @@ bool MQTTFanComponent::publish_state() {
|
||||
this->publish(this->get_state_topic_to_(topic_buf), state_s);
|
||||
bool failed = false;
|
||||
if (this->state_->get_traits().supports_direction()) {
|
||||
bool success = this->publish(this->get_direction_state_topic_to(topic_buf),
|
||||
fan_direction_to_mqtt_str(this->state_->direction));
|
||||
bool success = this->publish(this->get_direction_state_topic(), fan_direction_to_mqtt_str(this->state_->direction));
|
||||
failed = failed || !success;
|
||||
}
|
||||
if (this->state_->get_traits().supports_oscillation()) {
|
||||
bool success = this->publish(this->get_oscillation_state_topic_to(topic_buf),
|
||||
fan_oscillation_to_mqtt_str(this->state_->oscillating));
|
||||
bool success =
|
||||
this->publish(this->get_oscillation_state_topic(), fan_oscillation_to_mqtt_str(this->state_->oscillating));
|
||||
failed = failed || !success;
|
||||
}
|
||||
auto traits = this->state_->get_traits();
|
||||
if (traits.supports_speed()) {
|
||||
char buf[12];
|
||||
size_t len = buf_append_printf(buf, sizeof(buf), 0, "%d", this->state_->speed);
|
||||
bool success = this->publish(this->get_speed_level_state_topic_to(topic_buf), buf, len);
|
||||
bool success = this->publish(this->get_speed_level_state_topic(), buf, len);
|
||||
failed = failed || !success;
|
||||
}
|
||||
return !failed;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "mqtt_number.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
#include "mqtt_const.h"
|
||||
|
||||
@@ -13,9 +12,6 @@ static const char *const TAG = "mqtt.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) {}
|
||||
|
||||
void MQTTNumberComponent::setup() {
|
||||
@@ -52,10 +48,15 @@ void MQTTNumberComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCon
|
||||
if (!unit_of_measurement.empty()) {
|
||||
root[MQTT_UNIT_OF_MEASUREMENT] = unit_of_measurement;
|
||||
}
|
||||
const auto mode = this->number_->traits.get_mode();
|
||||
if (mode != NUMBER_MODE_AUTO) {
|
||||
root[MQTT_MODE] =
|
||||
NumberMqttModeStrings::get_progmem_str(static_cast<uint8_t>(mode), static_cast<uint8_t>(NUMBER_MODE_BOX));
|
||||
switch (this->number_->traits.get_mode()) {
|
||||
case NUMBER_MODE_AUTO:
|
||||
break;
|
||||
case 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();
|
||||
if (!device_class.empty()) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "mqtt_text.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
#include "mqtt_const.h"
|
||||
|
||||
@@ -13,9 +12,6 @@ static const char *const TAG = "mqtt.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) {}
|
||||
|
||||
void MQTTTextComponent::setup() {
|
||||
@@ -38,8 +34,14 @@ const EntityBase *MQTTTextComponent::get_entity() const { return this->text_; }
|
||||
|
||||
void MQTTTextComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[MQTT_MODE] = TextMqttModeStrings::get_progmem_str(static_cast<uint8_t>(this->text_->traits.get_mode()),
|
||||
static_cast<uint8_t>(TEXT_MODE_TEXT));
|
||||
switch (this->text_->traits.get_mode()) {
|
||||
case TEXT_MODE_TEXT:
|
||||
root[MQTT_MODE] = "text";
|
||||
break;
|
||||
case TEXT_MODE_PASSWORD:
|
||||
root[MQTT_MODE] = "password";
|
||||
break;
|
||||
}
|
||||
|
||||
config.command_topic = true;
|
||||
}
|
||||
|
||||
@@ -87,13 +87,13 @@ bool MQTTValveComponent::send_initial_state() { return this->publish_state(); }
|
||||
bool MQTTValveComponent::publish_state() {
|
||||
auto traits = this->valve_->get_traits();
|
||||
bool success = true;
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (traits.get_supports_position()) {
|
||||
char pos[VALUE_ACCURACY_MAX_LEN];
|
||||
size_t len = value_accuracy_to_buf(pos, roundf(this->valve_->position * 100), 0);
|
||||
if (!this->publish(this->get_position_state_topic_to(topic_buf), pos, len))
|
||||
if (!this->publish(this->get_position_state_topic(), pos, len))
|
||||
success = false;
|
||||
}
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (!this->publish(this->get_state_topic_to_(topic_buf),
|
||||
valve_state_to_mqtt_str(this->valve_->current_operation, this->valve_->position,
|
||||
traits.get_supports_position())))
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/progmem.h"
|
||||
|
||||
namespace esphome::template_ {
|
||||
|
||||
@@ -29,11 +28,18 @@ void TemplateAlarmControlPanel::add_sensor(binary_sensor::BinarySensor *sensor,
|
||||
this->sensor_data_.push_back(sd);
|
||||
};
|
||||
|
||||
// Alarm sensor type strings indexed by AlarmSensorType enum (0-3): DELAYED, INSTANT, DELAYED_FOLLOWER, INSTANT_ALWAYS
|
||||
PROGMEM_STRING_TABLE(AlarmSensorTypeStrings, "delayed", "instant", "delayed_follower", "instant_always");
|
||||
|
||||
static const LogString *sensor_type_to_string(AlarmSensorType type) {
|
||||
return AlarmSensorTypeStrings::get_log_str(static_cast<uint8_t>(type), 0);
|
||||
switch (type) {
|
||||
case ALARM_SENSOR_TYPE_INSTANT:
|
||||
return LOG_STR("instant");
|
||||
case ALARM_SENSOR_TYPE_DELAYED_FOLLOWER:
|
||||
return LOG_STR("delayed_follower");
|
||||
case ALARM_SENSOR_TYPE_INSTANT_ALWAYS:
|
||||
return LOG_STR("instant_always");
|
||||
case ALARM_SENSOR_TYPE_DELAYED:
|
||||
default:
|
||||
return LOG_STR("delayed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ enum BinarySensorFlags : uint16_t {
|
||||
BINARY_SENSOR_MODE_BYPASS_AUTO = 1 << 4,
|
||||
};
|
||||
|
||||
enum AlarmSensorType : uint8_t {
|
||||
enum AlarmSensorType : uint16_t {
|
||||
ALARM_SENSOR_TYPE_DELAYED = 0,
|
||||
ALARM_SENSOR_TYPE_INSTANT,
|
||||
ALARM_SENSOR_TYPE_DELAYED_FOLLOWER,
|
||||
|
||||
@@ -37,7 +37,7 @@ lib_deps_base =
|
||||
wjtje/qr-code-generator-library@1.7.0 ; qr_code
|
||||
functionpointer/arduino-MLX90393@1.0.2 ; mlx90393
|
||||
pavlodn/HaierProtocol@0.9.31 ; haier
|
||||
esphome/dsmr_parser@1.1.0 ; dsmr
|
||||
esphome/dsmr_parser@1.0.0 ; dsmr
|
||||
polargoose/Crypto-no-arduino@0.4.0 ; dsmr
|
||||
https://github.com/esphome/TinyGPSPlus.git#v1.1.0 ; gps
|
||||
; This is using the repository until a new release is published to PlatformIO
|
||||
|
||||
@@ -23,7 +23,6 @@ resvg-py==0.2.6
|
||||
freetype-py==2.5.1
|
||||
jinja2==3.1.6
|
||||
bleak==2.1.1
|
||||
requests==2.32.5
|
||||
|
||||
# esp-idf >= 5.0 requires this
|
||||
pyparsing >= 3.0
|
||||
|
||||
Reference in New Issue
Block a user