mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 21:44:55 +01:00
Mqtt topics to support numeric fan speed (#1859)
* numeric speed added * when dumping config for MQTT components log a note when skipped due to is_internal * added new topics to paython code validation/generation * reformatted with black * formatting corrected * use dump_config_ mechanism to skip internal components * use dump_config_ mechanism to skip internal components * style issues resolved * do_dump_config removed * formatting fixed * formatting fixed * Drop parent dump_config() calls Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
parent
e32722db70
commit
fd836e982e
5 changed files with 73 additions and 0 deletions
|
@ -12,6 +12,8 @@ from esphome.const import (
|
||||||
CONF_OSCILLATION_COMMAND_TOPIC,
|
CONF_OSCILLATION_COMMAND_TOPIC,
|
||||||
CONF_OSCILLATION_STATE_TOPIC,
|
CONF_OSCILLATION_STATE_TOPIC,
|
||||||
CONF_SPEED,
|
CONF_SPEED,
|
||||||
|
CONF_SPEED_LEVEL_COMMAND_TOPIC,
|
||||||
|
CONF_SPEED_LEVEL_STATE_TOPIC,
|
||||||
CONF_SPEED_COMMAND_TOPIC,
|
CONF_SPEED_COMMAND_TOPIC,
|
||||||
CONF_SPEED_STATE_TOPIC,
|
CONF_SPEED_STATE_TOPIC,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
|
@ -57,6 +59,12 @@ FAN_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||||
cv.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.All(
|
cv.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.All(
|
||||||
cv.requires_component("mqtt"), cv.subscribe_topic
|
cv.requires_component("mqtt"), cv.subscribe_topic
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_SPEED_LEVEL_STATE_TOPIC): cv.All(
|
||||||
|
cv.requires_component("mqtt"), cv.publish_topic
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SPEED_LEVEL_COMMAND_TOPIC): cv.All(
|
||||||
|
cv.requires_component("mqtt"), cv.subscribe_topic
|
||||||
|
),
|
||||||
cv.Optional(CONF_SPEED_STATE_TOPIC): cv.All(
|
cv.Optional(CONF_SPEED_STATE_TOPIC): cv.All(
|
||||||
cv.requires_component("mqtt"), cv.publish_topic
|
cv.requires_component("mqtt"), cv.publish_topic
|
||||||
),
|
),
|
||||||
|
@ -104,6 +112,18 @@ async def setup_fan_core_(var, config):
|
||||||
config[CONF_OSCILLATION_COMMAND_TOPIC]
|
config[CONF_OSCILLATION_COMMAND_TOPIC]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if CONF_SPEED_LEVEL_STATE_TOPIC in config:
|
||||||
|
cg.add(
|
||||||
|
mqtt_.set_custom_speed_level_state_topic(
|
||||||
|
config[CONF_SPEED_LEVEL_STATE_TOPIC]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if CONF_SPEED_LEVEL_COMMAND_TOPIC in config:
|
||||||
|
cg.add(
|
||||||
|
mqtt_.set_custom_speed_level_command_topic(
|
||||||
|
config[CONF_SPEED_LEVEL_COMMAND_TOPIC]
|
||||||
|
)
|
||||||
|
)
|
||||||
if CONF_SPEED_STATE_TOPIC in config:
|
if CONF_SPEED_STATE_TOPIC in config:
|
||||||
cg.add(mqtt_.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
|
cg.add(mqtt_.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
|
||||||
if CONF_SPEED_COMMAND_TOPIC in config:
|
if CONF_SPEED_COMMAND_TOPIC in config:
|
||||||
|
|
|
@ -16,6 +16,7 @@ MQTTFanComponent::MQTTFanComponent(FanState *state) : MQTTComponent(), state_(st
|
||||||
|
|
||||||
FanState *MQTTFanComponent::get_state() const { return this->state_; }
|
FanState *MQTTFanComponent::get_state() const { return this->state_; }
|
||||||
std::string MQTTFanComponent::component_type() const { return "fan"; }
|
std::string MQTTFanComponent::component_type() const { return "fan"; }
|
||||||
|
|
||||||
void MQTTFanComponent::setup() {
|
void MQTTFanComponent::setup() {
|
||||||
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
|
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
|
||||||
auto val = parse_on_off(payload.c_str());
|
auto val = parse_on_off(payload.c_str());
|
||||||
|
@ -64,6 +65,26 @@ void MQTTFanComponent::setup() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->state_->get_traits().supports_speed()) {
|
||||||
|
this->subscribe(this->get_speed_level_command_topic(),
|
||||||
|
[this](const std::string &topic, const std::string &payload) {
|
||||||
|
optional<int> speed_level_opt = parse_int(payload);
|
||||||
|
if (speed_level_opt.has_value()) {
|
||||||
|
const int speed_level = speed_level_opt.value();
|
||||||
|
if (speed_level >= 0 && speed_level <= this->state_->get_traits().supported_speed_count()) {
|
||||||
|
ESP_LOGD(TAG, "New speed level %d", speed_level);
|
||||||
|
this->state_->make_call().set_speed(speed_level).perform();
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Invalid speed level %d", speed_level);
|
||||||
|
this->status_momentary_warning("speed", 5000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Invalid speed level %s (int expected)", payload.c_str());
|
||||||
|
this->status_momentary_warning("speed", 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (this->state_->get_traits().supports_speed()) {
|
if (this->state_->get_traits().supports_speed()) {
|
||||||
this->subscribe(this->get_speed_command_topic(), [this](const std::string &topic, const std::string &payload) {
|
this->subscribe(this->get_speed_command_topic(), [this](const std::string &topic, const std::string &payload) {
|
||||||
this->state_->make_call()
|
this->state_->make_call()
|
||||||
|
@ -75,6 +96,22 @@ void MQTTFanComponent::setup() {
|
||||||
auto f = std::bind(&MQTTFanComponent::publish_state, this);
|
auto f = std::bind(&MQTTFanComponent::publish_state, this);
|
||||||
this->state_->add_on_state_callback([this, f]() { this->defer("send", f); });
|
this->state_->add_on_state_callback([this, f]() { this->defer("send", f); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MQTTFanComponent::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "MQTT Fan '%s': ", this->state_->get_name().c_str());
|
||||||
|
LOG_MQTT_COMPONENT(true, true);
|
||||||
|
if (this->state_->get_traits().supports_oscillation()) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Oscillation State Topic: '%s'", this->get_oscillation_state_topic().c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " Oscillation Command Topic: '%s'", this->get_oscillation_command_topic().c_str());
|
||||||
|
}
|
||||||
|
if (this->state_->get_traits().supports_speed()) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Speed Level State Topic: '%s'", this->get_speed_level_state_topic().c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " Speed Level Command Topic: '%s'", this->get_speed_level_command_topic().c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " Speed State Topic: '%s'", this->get_speed_state_topic().c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " Speed Command Topic: '%s'", this->get_speed_command_topic().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MQTTFanComponent::send_initial_state() { return this->publish_state(); }
|
bool MQTTFanComponent::send_initial_state() { return this->publish_state(); }
|
||||||
std::string MQTTFanComponent::friendly_name() const { return this->state_->get_name(); }
|
std::string MQTTFanComponent::friendly_name() const { return this->state_->get_name(); }
|
||||||
void MQTTFanComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
void MQTTFanComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||||
|
@ -83,6 +120,8 @@ void MQTTFanComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfi
|
||||||
root["oscillation_state_topic"] = this->get_oscillation_state_topic();
|
root["oscillation_state_topic"] = this->get_oscillation_state_topic();
|
||||||
}
|
}
|
||||||
if (this->state_->get_traits().supports_speed()) {
|
if (this->state_->get_traits().supports_speed()) {
|
||||||
|
root["speed_level_command_topic"] = this->get_speed_level_command_topic();
|
||||||
|
root["speed_level_state_topic"] = this->get_speed_level_state_topic();
|
||||||
root["speed_command_topic"] = this->get_speed_command_topic();
|
root["speed_command_topic"] = this->get_speed_command_topic();
|
||||||
root["speed_state_topic"] = this->get_speed_state_topic();
|
root["speed_state_topic"] = this->get_speed_state_topic();
|
||||||
}
|
}
|
||||||
|
@ -99,6 +138,11 @@ bool MQTTFanComponent::publish_state() {
|
||||||
failed = failed || !success;
|
failed = failed || !success;
|
||||||
}
|
}
|
||||||
auto traits = this->state_->get_traits();
|
auto traits = this->state_->get_traits();
|
||||||
|
if (traits.supports_speed()) {
|
||||||
|
std::string payload = to_string(this->state_->speed);
|
||||||
|
bool success = this->publish(this->get_speed_level_state_topic(), payload);
|
||||||
|
failed = failed || !success;
|
||||||
|
}
|
||||||
if (traits.supports_speed()) {
|
if (traits.supports_speed()) {
|
||||||
const char *payload;
|
const char *payload;
|
||||||
// NOLINTNEXTLINE(clang-diagnostic-deprecated-declarations)
|
// NOLINTNEXTLINE(clang-diagnostic-deprecated-declarations)
|
||||||
|
|
|
@ -17,6 +17,8 @@ class MQTTFanComponent : public mqtt::MQTTComponent {
|
||||||
|
|
||||||
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, command)
|
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, command)
|
||||||
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, state)
|
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, state)
|
||||||
|
MQTT_COMPONENT_CUSTOM_TOPIC(speed_level, command)
|
||||||
|
MQTT_COMPONENT_CUSTOM_TOPIC(speed_level, state)
|
||||||
MQTT_COMPONENT_CUSTOM_TOPIC(speed, command)
|
MQTT_COMPONENT_CUSTOM_TOPIC(speed, command)
|
||||||
MQTT_COMPONENT_CUSTOM_TOPIC(speed, state)
|
MQTT_COMPONENT_CUSTOM_TOPIC(speed, state)
|
||||||
|
|
||||||
|
@ -26,6 +28,9 @@ class MQTTFanComponent : public mqtt::MQTTComponent {
|
||||||
// (In most use cases you won't need these)
|
// (In most use cases you won't need these)
|
||||||
/// Setup the fan subscriptions and discovery.
|
/// Setup the fan subscriptions and discovery.
|
||||||
void setup() override;
|
void setup() override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
/// Send the full current state to MQTT.
|
/// Send the full current state to MQTT.
|
||||||
bool send_initial_state() override;
|
bool send_initial_state() override;
|
||||||
bool publish_state();
|
bool publish_state();
|
||||||
|
|
|
@ -597,6 +597,8 @@ CONF_SOURCE = "source"
|
||||||
CONF_SPEED = "speed"
|
CONF_SPEED = "speed"
|
||||||
CONF_SPEED_COMMAND_TOPIC = "speed_command_topic"
|
CONF_SPEED_COMMAND_TOPIC = "speed_command_topic"
|
||||||
CONF_SPEED_COUNT = "speed_count"
|
CONF_SPEED_COUNT = "speed_count"
|
||||||
|
CONF_SPEED_LEVEL_COMMAND_TOPIC = "speed_level_command_topic"
|
||||||
|
CONF_SPEED_LEVEL_STATE_TOPIC = "speed_level_state_topic"
|
||||||
CONF_SPEED_STATE_TOPIC = "speed_state_topic"
|
CONF_SPEED_STATE_TOPIC = "speed_state_topic"
|
||||||
CONF_SPI_ID = "spi_id"
|
CONF_SPI_ID = "spi_id"
|
||||||
CONF_SPIKE_REJECTION = "spike_rejection"
|
CONF_SPIKE_REJECTION = "spike_rejection"
|
||||||
|
|
|
@ -1978,6 +1978,8 @@ fan:
|
||||||
direction_output: gpio_26
|
direction_output: gpio_26
|
||||||
oscillation_state_topic: oscillation/state/topic
|
oscillation_state_topic: oscillation/state/topic
|
||||||
oscillation_command_topic: oscillation/command/topic
|
oscillation_command_topic: oscillation/command/topic
|
||||||
|
speed_level_state_topic: speed_level/state/topic
|
||||||
|
speed_level_command_topic: speed_level/command/topic
|
||||||
speed_state_topic: speed/state/topic
|
speed_state_topic: speed/state/topic
|
||||||
speed_command_topic: speed/command/topic
|
speed_command_topic: speed/command/topic
|
||||||
on_speed_set:
|
on_speed_set:
|
||||||
|
|
Loading…
Reference in a new issue