mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 06:58:11 +01:00
Add support for button entities (#2824)
This commit is contained in:
parent
f50e40e0b8
commit
b5639a6472
34 changed files with 697 additions and 0 deletions
|
@ -30,6 +30,7 @@ esphome/components/bang_bang/* @OttoWinter
|
||||||
esphome/components/binary_sensor/* @esphome/core
|
esphome/components/binary_sensor/* @esphome/core
|
||||||
esphome/components/ble_client/* @buxtronix
|
esphome/components/ble_client/* @buxtronix
|
||||||
esphome/components/bme680_bsec/* @trvrnrth
|
esphome/components/bme680_bsec/* @trvrnrth
|
||||||
|
esphome/components/button/* @esphome/core
|
||||||
esphome/components/canbus/* @danielschramm @mvturnho
|
esphome/components/canbus/* @danielschramm @mvturnho
|
||||||
esphome/components/cap1188/* @MrEditor97
|
esphome/components/cap1188/* @MrEditor97
|
||||||
esphome/components/captive_portal/* @OttoWinter
|
esphome/components/captive_portal/* @OttoWinter
|
||||||
|
|
|
@ -40,6 +40,7 @@ service APIConnection {
|
||||||
rpc climate_command (ClimateCommandRequest) returns (void) {}
|
rpc climate_command (ClimateCommandRequest) returns (void) {}
|
||||||
rpc number_command (NumberCommandRequest) returns (void) {}
|
rpc number_command (NumberCommandRequest) returns (void) {}
|
||||||
rpc select_command (SelectCommandRequest) returns (void) {}
|
rpc select_command (SelectCommandRequest) returns (void) {}
|
||||||
|
rpc button_command (ButtonCommandRequest) returns (void) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -944,3 +945,27 @@ message SelectCommandRequest {
|
||||||
fixed32 key = 1;
|
fixed32 key = 1;
|
||||||
string state = 2;
|
string state = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== BUTTON ====================
|
||||||
|
message ListEntitiesButtonResponse {
|
||||||
|
option (id) = 61;
|
||||||
|
option (source) = SOURCE_SERVER;
|
||||||
|
option (ifdef) = "USE_BUTTON";
|
||||||
|
|
||||||
|
string object_id = 1;
|
||||||
|
fixed32 key = 2;
|
||||||
|
string name = 3;
|
||||||
|
string unique_id = 4;
|
||||||
|
|
||||||
|
string icon = 5;
|
||||||
|
bool disabled_by_default = 6;
|
||||||
|
EntityCategory entity_category = 7;
|
||||||
|
}
|
||||||
|
message ButtonCommandRequest {
|
||||||
|
option (id) = 62;
|
||||||
|
option (source) = SOURCE_CLIENT;
|
||||||
|
option (ifdef) = "USE_BUTTON";
|
||||||
|
option (no_delay) = true;
|
||||||
|
|
||||||
|
fixed32 key = 1;
|
||||||
|
}
|
||||||
|
|
|
@ -674,6 +674,27 @@ void APIConnection::select_command(const SelectCommandRequest &msg) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool APIConnection::send_button_info(button::Button *button) {
|
||||||
|
ListEntitiesButtonResponse msg;
|
||||||
|
msg.key = button->get_object_id_hash();
|
||||||
|
msg.object_id = button->get_object_id();
|
||||||
|
msg.name = button->get_name();
|
||||||
|
msg.unique_id = get_default_unique_id("button", button);
|
||||||
|
msg.icon = button->get_icon();
|
||||||
|
msg.disabled_by_default = button->is_disabled_by_default();
|
||||||
|
msg.entity_category = static_cast<enums::EntityCategory>(button->get_entity_category());
|
||||||
|
return this->send_list_entities_button_response(msg);
|
||||||
|
}
|
||||||
|
void APIConnection::button_command(const ButtonCommandRequest &msg) {
|
||||||
|
button::Button *button = App.get_button_by_key(msg.key);
|
||||||
|
if (button == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
button->press();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
void APIConnection::send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image) {
|
void APIConnection::send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image) {
|
||||||
if (!this->state_subscription_)
|
if (!this->state_subscription_)
|
||||||
|
|
|
@ -73,6 +73,10 @@ class APIConnection : public APIServerConnection {
|
||||||
bool send_select_state(select::Select *select, std::string state);
|
bool send_select_state(select::Select *select, std::string state);
|
||||||
bool send_select_info(select::Select *select);
|
bool send_select_info(select::Select *select);
|
||||||
void select_command(const SelectCommandRequest &msg) override;
|
void select_command(const SelectCommandRequest &msg) override;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool send_button_info(button::Button *button);
|
||||||
|
void button_command(const ButtonCommandRequest &msg) override;
|
||||||
#endif
|
#endif
|
||||||
bool send_log_message(int level, const char *tag, const char *line);
|
bool send_log_message(int level, const char *tag, const char *line);
|
||||||
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
||||||
|
|
|
@ -4147,6 +4147,118 @@ void SelectCommandRequest::dump_to(std::string &out) const {
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
bool ListEntitiesButtonResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||||
|
switch (field_id) {
|
||||||
|
case 6: {
|
||||||
|
this->disabled_by_default = value.as_bool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 7: {
|
||||||
|
this->entity_category = value.as_enum<enums::EntityCategory>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool ListEntitiesButtonResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||||
|
switch (field_id) {
|
||||||
|
case 1: {
|
||||||
|
this->object_id = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
this->name = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
this->unique_id = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
this->icon = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool ListEntitiesButtonResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||||
|
switch (field_id) {
|
||||||
|
case 2: {
|
||||||
|
this->key = value.as_fixed32();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ListEntitiesButtonResponse::encode(ProtoWriteBuffer buffer) const {
|
||||||
|
buffer.encode_string(1, this->object_id);
|
||||||
|
buffer.encode_fixed32(2, this->key);
|
||||||
|
buffer.encode_string(3, this->name);
|
||||||
|
buffer.encode_string(4, this->unique_id);
|
||||||
|
buffer.encode_string(5, this->icon);
|
||||||
|
buffer.encode_bool(6, this->disabled_by_default);
|
||||||
|
buffer.encode_enum<enums::EntityCategory>(7, this->entity_category);
|
||||||
|
}
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
void ListEntitiesButtonResponse::dump_to(std::string &out) const {
|
||||||
|
char buffer[64];
|
||||||
|
out.append("ListEntitiesButtonResponse {\n");
|
||||||
|
out.append(" object_id: ");
|
||||||
|
out.append("'").append(this->object_id).append("'");
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" key: ");
|
||||||
|
sprintf(buffer, "%u", this->key);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" name: ");
|
||||||
|
out.append("'").append(this->name).append("'");
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" unique_id: ");
|
||||||
|
out.append("'").append(this->unique_id).append("'");
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" icon: ");
|
||||||
|
out.append("'").append(this->icon).append("'");
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" disabled_by_default: ");
|
||||||
|
out.append(YESNO(this->disabled_by_default));
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" entity_category: ");
|
||||||
|
out.append(proto_enum_to_string<enums::EntityCategory>(this->entity_category));
|
||||||
|
out.append("\n");
|
||||||
|
out.append("}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bool ButtonCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||||
|
switch (field_id) {
|
||||||
|
case 1: {
|
||||||
|
this->key = value.as_fixed32();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ButtonCommandRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->key); }
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
void ButtonCommandRequest::dump_to(std::string &out) const {
|
||||||
|
char buffer[64];
|
||||||
|
out.append("ButtonCommandRequest {\n");
|
||||||
|
out.append(" key: ");
|
||||||
|
sprintf(buffer, "%u", this->key);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\n");
|
||||||
|
out.append("}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -1041,6 +1041,36 @@ class SelectCommandRequest : public ProtoMessage {
|
||||||
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
|
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
|
||||||
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
||||||
};
|
};
|
||||||
|
class ListEntitiesButtonResponse : public ProtoMessage {
|
||||||
|
public:
|
||||||
|
std::string object_id{};
|
||||||
|
uint32_t key{0};
|
||||||
|
std::string name{};
|
||||||
|
std::string unique_id{};
|
||||||
|
std::string icon{};
|
||||||
|
bool disabled_by_default{false};
|
||||||
|
enums::EntityCategory entity_category{};
|
||||||
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
void dump_to(std::string &out) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
|
||||||
|
bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
|
||||||
|
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
|
||||||
|
};
|
||||||
|
class ButtonCommandRequest : public ProtoMessage {
|
||||||
|
public:
|
||||||
|
uint32_t key{0};
|
||||||
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
void dump_to(std::string &out) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -282,6 +282,16 @@ bool APIServerConnectionBase::send_select_state_response(const SelectStateRespon
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool APIServerConnectionBase::send_list_entities_button_response(const ListEntitiesButtonResponse &msg) {
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
ESP_LOGVV(TAG, "send_list_entities_button_response: %s", msg.dump().c_str());
|
||||||
|
#endif
|
||||||
|
return this->send_message_<ListEntitiesButtonResponse>(msg, 61);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
#endif
|
||||||
bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
|
bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
|
||||||
switch (msg_type) {
|
switch (msg_type) {
|
||||||
case 1: {
|
case 1: {
|
||||||
|
@ -513,6 +523,17 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||||
ESP_LOGVV(TAG, "on_select_command_request: %s", msg.dump().c_str());
|
ESP_LOGVV(TAG, "on_select_command_request: %s", msg.dump().c_str());
|
||||||
#endif
|
#endif
|
||||||
this->on_select_command_request(msg);
|
this->on_select_command_request(msg);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 62: {
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
ButtonCommandRequest msg;
|
||||||
|
msg.decode(msg_data, msg_size);
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
ESP_LOGVV(TAG, "on_button_command_request: %s", msg.dump().c_str());
|
||||||
|
#endif
|
||||||
|
this->on_button_command_request(msg);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -737,6 +758,19 @@ void APIServerConnection::on_select_command_request(const SelectCommandRequest &
|
||||||
this->select_command(msg);
|
this->select_command(msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
void APIServerConnection::on_button_command_request(const ButtonCommandRequest &msg) {
|
||||||
|
if (!this->is_connection_setup()) {
|
||||||
|
this->on_no_setup_connection();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this->is_authenticated()) {
|
||||||
|
this->on_unauthenticated_access();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->button_command(msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -129,6 +129,12 @@ class APIServerConnectionBase : public ProtoService {
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
virtual void on_select_command_request(const SelectCommandRequest &value){};
|
virtual void on_select_command_request(const SelectCommandRequest &value){};
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool send_list_entities_button_response(const ListEntitiesButtonResponse &msg);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
virtual void on_button_command_request(const ButtonCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
|
bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
|
||||||
|
@ -171,6 +177,9 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
virtual void select_command(const SelectCommandRequest &msg) = 0;
|
virtual void select_command(const SelectCommandRequest &msg) = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
virtual void button_command(const ButtonCommandRequest &msg) = 0;
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
void on_hello_request(const HelloRequest &msg) override;
|
void on_hello_request(const HelloRequest &msg) override;
|
||||||
|
@ -209,6 +218,9 @@ class APIServerConnection : public APIServerConnectionBase {
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
void on_select_command_request(const SelectCommandRequest &msg) override;
|
void on_select_command_request(const SelectCommandRequest &msg) override;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
void on_button_command_request(const ButtonCommandRequest &msg) override;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
|
@ -27,6 +27,9 @@ bool ListEntitiesIterator::on_sensor(sensor::Sensor *sensor) { return this->clie
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
bool ListEntitiesIterator::on_switch(switch_::Switch *a_switch) { return this->client_->send_switch_info(a_switch); }
|
bool ListEntitiesIterator::on_switch(switch_::Switch *a_switch) { return this->client_->send_switch_info(a_switch); }
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool ListEntitiesIterator::on_button(button::Button *button) { return this->client_->send_button_info(button); }
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
bool ListEntitiesIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
|
bool ListEntitiesIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
|
||||||
return this->client_->send_text_sensor_info(text_sensor);
|
return this->client_->send_text_sensor_info(text_sensor);
|
||||||
|
|
|
@ -30,6 +30,9 @@ class ListEntitiesIterator : public ComponentIterator {
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
bool on_switch(switch_::Switch *a_switch) override;
|
bool on_switch(switch_::Switch *a_switch) override;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool on_button(button::Button *button) override;
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
bool on_text_sensor(text_sensor::TextSensor *text_sensor) override;
|
bool on_text_sensor(text_sensor::TextSensor *text_sensor) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,9 @@ class InitialStateIterator : public ComponentIterator {
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
bool on_switch(switch_::Switch *a_switch) override;
|
bool on_switch(switch_::Switch *a_switch) override;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
bool on_button(button::Button *button) override { return true; };
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
bool on_text_sensor(text_sensor::TextSensor *text_sensor) override;
|
bool on_text_sensor(text_sensor::TextSensor *text_sensor) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -116,6 +116,21 @@ void ComponentIterator::advance() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
case IteratorState::BUTTON:
|
||||||
|
if (this->at_ >= App.get_buttons().size()) {
|
||||||
|
advance_platform = true;
|
||||||
|
} else {
|
||||||
|
auto *button = App.get_buttons()[this->at_];
|
||||||
|
if (button->is_internal()) {
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
success = this->on_button(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
case IteratorState::TEXT_SENSOR:
|
case IteratorState::TEXT_SENSOR:
|
||||||
if (this->at_ >= App.get_text_sensors().size()) {
|
if (this->at_ >= App.get_text_sensors().size()) {
|
||||||
|
|
|
@ -38,6 +38,9 @@ class ComponentIterator {
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
virtual bool on_switch(switch_::Switch *a_switch) = 0;
|
virtual bool on_switch(switch_::Switch *a_switch) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
virtual bool on_button(button::Button *button) = 0;
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
virtual bool on_text_sensor(text_sensor::TextSensor *text_sensor) = 0;
|
virtual bool on_text_sensor(text_sensor::TextSensor *text_sensor) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,6 +81,9 @@ class ComponentIterator {
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
SWITCH,
|
SWITCH,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
BUTTON,
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
TEXT_SENSOR,
|
TEXT_SENSOR,
|
||||||
#endif
|
#endif
|
||||||
|
|
104
esphome/components/button/__init__.py
Normal file
104
esphome/components/button/__init__.py
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome import automation
|
||||||
|
from esphome.automation import maybe_simple_id
|
||||||
|
from esphome.components import mqtt
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_ENTITY_CATEGORY,
|
||||||
|
CONF_ICON,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_ON_PRESS,
|
||||||
|
CONF_TRIGGER_ID,
|
||||||
|
CONF_MQTT_ID,
|
||||||
|
)
|
||||||
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
|
from esphome.cpp_helpers import setup_entity
|
||||||
|
|
||||||
|
CODEOWNERS = ["@esphome/core"]
|
||||||
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
|
button_ns = cg.esphome_ns.namespace("button")
|
||||||
|
Button = button_ns.class_("Button", cg.EntityBase)
|
||||||
|
ButtonPtr = Button.operator("ptr")
|
||||||
|
|
||||||
|
PressAction = button_ns.class_("PressAction", automation.Action)
|
||||||
|
|
||||||
|
ButtonPressTrigger = button_ns.class_(
|
||||||
|
"ButtonPressTrigger", automation.Trigger.template()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
BUTTON_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTButtonComponent),
|
||||||
|
cv.Optional(CONF_ON_PRESS): automation.validate_automation(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ButtonPressTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
_UNDEF = object()
|
||||||
|
|
||||||
|
|
||||||
|
def button_schema(
|
||||||
|
icon: str = _UNDEF,
|
||||||
|
entity_category: str = _UNDEF,
|
||||||
|
) -> cv.Schema:
|
||||||
|
schema = BUTTON_SCHEMA
|
||||||
|
if icon is not _UNDEF:
|
||||||
|
schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
|
||||||
|
if entity_category is not _UNDEF:
|
||||||
|
schema = schema.extend(
|
||||||
|
{
|
||||||
|
cv.Optional(
|
||||||
|
CONF_ENTITY_CATEGORY, default=entity_category
|
||||||
|
): cv.entity_category
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return schema
|
||||||
|
|
||||||
|
|
||||||
|
async def setup_button_core_(var, config):
|
||||||
|
await setup_entity(var, config)
|
||||||
|
|
||||||
|
for conf in config.get(CONF_ON_PRESS, []):
|
||||||
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
|
||||||
|
if CONF_MQTT_ID in config:
|
||||||
|
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
||||||
|
await mqtt.register_mqtt_component(mqtt_, config)
|
||||||
|
|
||||||
|
|
||||||
|
async def register_button(var, config):
|
||||||
|
if not CORE.has_id(config[CONF_ID]):
|
||||||
|
var = cg.Pvariable(config[CONF_ID], var)
|
||||||
|
cg.add(cg.App.register_button(var))
|
||||||
|
await setup_button_core_(var, config)
|
||||||
|
|
||||||
|
|
||||||
|
async def new_button(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await register_button(var, config)
|
||||||
|
return var
|
||||||
|
|
||||||
|
|
||||||
|
BUTTON_PRESS_SCHEMA = maybe_simple_id(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_ID): cv.use_id(Button),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action("button.press", PressAction, BUTTON_PRESS_SCHEMA)
|
||||||
|
async def button_press_to_code(config, action_id, template_arg, args):
|
||||||
|
paren = await cg.get_variable(config[CONF_ID])
|
||||||
|
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||||
|
|
||||||
|
|
||||||
|
@coroutine_with_priority(100.0)
|
||||||
|
async def to_code(config):
|
||||||
|
cg.add_global(button_ns.using)
|
||||||
|
cg.add_define("USE_BUTTON")
|
28
esphome/components/button/automation.h
Normal file
28
esphome/components/button/automation.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/button/button.h"
|
||||||
|
#include "esphome/core/automation.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace button {
|
||||||
|
|
||||||
|
template<typename... Ts> class PressAction : public Action<Ts...> {
|
||||||
|
public:
|
||||||
|
explicit PressAction(Button *button) : button_(button) {}
|
||||||
|
|
||||||
|
void play(Ts... x) override { this->button_->press(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Button *button_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ButtonPressTrigger : public Trigger<> {
|
||||||
|
public:
|
||||||
|
ButtonPressTrigger(Button *button) {
|
||||||
|
button->add_on_press_callback([this]() { this->trigger(); });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace button
|
||||||
|
} // namespace esphome
|
21
esphome/components/button/button.cpp
Normal file
21
esphome/components/button/button.cpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "button.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace button {
|
||||||
|
|
||||||
|
static const char *const TAG = "button";
|
||||||
|
|
||||||
|
Button::Button(const std::string &name) : EntityBase(name) {}
|
||||||
|
Button::Button() : Button("") {}
|
||||||
|
|
||||||
|
void Button::press() {
|
||||||
|
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
|
||||||
|
this->press_action();
|
||||||
|
this->press_callback_.call();
|
||||||
|
}
|
||||||
|
void Button::add_on_press_callback(std::function<void()> &&callback) { this->press_callback_.add(std::move(callback)); }
|
||||||
|
uint32_t Button::hash_base() { return 1495763804UL; }
|
||||||
|
|
||||||
|
} // namespace button
|
||||||
|
} // namespace esphome
|
50
esphome/components/button/button.h
Normal file
50
esphome/components/button/button.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/entity_base.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace button {
|
||||||
|
|
||||||
|
#define LOG_BUTTON(prefix, type, obj) \
|
||||||
|
if ((obj) != nullptr) { \
|
||||||
|
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
|
||||||
|
if (!(obj)->get_icon().empty()) { \
|
||||||
|
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Base class for all buttons.
|
||||||
|
*
|
||||||
|
* A button is just a momentary switch that does not have a state, only a trigger.
|
||||||
|
*/
|
||||||
|
class Button : public EntityBase {
|
||||||
|
public:
|
||||||
|
explicit Button();
|
||||||
|
explicit Button(const std::string &name);
|
||||||
|
|
||||||
|
/** Press this button. This is called by the front-end.
|
||||||
|
*
|
||||||
|
* For implementing buttons, please override press_action.
|
||||||
|
*/
|
||||||
|
void press();
|
||||||
|
|
||||||
|
/** Set callback for state changes.
|
||||||
|
*
|
||||||
|
* @param callback The void() callback.
|
||||||
|
*/
|
||||||
|
void add_on_press_callback(std::function<void()> &&callback);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** You should implement this virtual method if you want to create your own button.
|
||||||
|
*/
|
||||||
|
virtual void press_action(){};
|
||||||
|
|
||||||
|
uint32_t hash_base() override;
|
||||||
|
|
||||||
|
CallbackManager<void()> press_callback_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace button
|
||||||
|
} // namespace esphome
|
|
@ -95,6 +95,7 @@ MQTTSwitchComponent = mqtt_ns.class_("MQTTSwitchComponent", MQTTComponent)
|
||||||
MQTTTextSensor = mqtt_ns.class_("MQTTTextSensor", MQTTComponent)
|
MQTTTextSensor = mqtt_ns.class_("MQTTTextSensor", MQTTComponent)
|
||||||
MQTTNumberComponent = mqtt_ns.class_("MQTTNumberComponent", MQTTComponent)
|
MQTTNumberComponent = mqtt_ns.class_("MQTTNumberComponent", MQTTComponent)
|
||||||
MQTTSelectComponent = mqtt_ns.class_("MQTTSelectComponent", MQTTComponent)
|
MQTTSelectComponent = mqtt_ns.class_("MQTTSelectComponent", MQTTComponent)
|
||||||
|
MQTTButtonComponent = mqtt_ns.class_("MQTTButtonComponent", MQTTComponent)
|
||||||
|
|
||||||
MQTTDiscoveryUniqueIdGenerator = mqtt_ns.enum("MQTTDiscoveryUniqueIdGenerator")
|
MQTTDiscoveryUniqueIdGenerator = mqtt_ns.enum("MQTTDiscoveryUniqueIdGenerator")
|
||||||
MQTT_DISCOVERY_UNIQUE_ID_GENERATOR_OPTIONS = {
|
MQTT_DISCOVERY_UNIQUE_ID_GENERATOR_OPTIONS = {
|
||||||
|
|
40
esphome/components/mqtt/mqtt_button.cpp
Normal file
40
esphome/components/mqtt/mqtt_button.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "mqtt_button.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#include "mqtt_const.h"
|
||||||
|
|
||||||
|
#ifdef USE_MQTT
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace mqtt {
|
||||||
|
|
||||||
|
static const char *const TAG = "mqtt.button";
|
||||||
|
|
||||||
|
using namespace esphome::button;
|
||||||
|
|
||||||
|
MQTTButtonComponent::MQTTButtonComponent(button::Button *button) : MQTTComponent(), button_(button) {}
|
||||||
|
|
||||||
|
void MQTTButtonComponent::setup() {
|
||||||
|
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
|
||||||
|
if (payload == "press") {
|
||||||
|
this->button_->press();
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name().c_str(), payload.c_str());
|
||||||
|
this->status_momentary_warning("state", 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
void MQTTButtonComponent::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "MQTT Button '%s': ", this->button_->get_name().c_str());
|
||||||
|
LOG_MQTT_COMPONENT(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MQTTButtonComponent::component_type() const { return "button"; }
|
||||||
|
const EntityBase *MQTTButtonComponent::get_entity() const { return this->button_; }
|
||||||
|
|
||||||
|
} // namespace mqtt
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif // USE_MQTT
|
40
esphome/components/mqtt/mqtt_button.h
Normal file
40
esphome/components/mqtt/mqtt_button.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
|
|
||||||
|
#ifdef USE_MQTT
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
|
||||||
|
#include "esphome/components/button/button.h"
|
||||||
|
#include "mqtt_component.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace mqtt {
|
||||||
|
|
||||||
|
class MQTTButtonComponent : public mqtt::MQTTComponent {
|
||||||
|
public:
|
||||||
|
explicit MQTTButtonComponent(button::Button *button);
|
||||||
|
|
||||||
|
// ========== INTERNAL METHODS ==========
|
||||||
|
// (In most use cases you won't need these)
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
/// Buttons do not send a state so just return true.
|
||||||
|
bool send_initial_state() override { return true; }
|
||||||
|
|
||||||
|
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// "button" component type.
|
||||||
|
std::string component_type() const override;
|
||||||
|
const EntityBase *get_entity() const override;
|
||||||
|
|
||||||
|
button::Button *button_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mqtt
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif // USE_MQTT
|
23
esphome/components/restart/button/__init__.py
Normal file
23
esphome/components/restart/button/__init__.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import button
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_ID,
|
||||||
|
ENTITY_CATEGORY_CONFIG,
|
||||||
|
ICON_RESTART,
|
||||||
|
)
|
||||||
|
|
||||||
|
restart_ns = cg.esphome_ns.namespace("restart")
|
||||||
|
RestartButton = restart_ns.class_("RestartButton", button.Button, cg.Component)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
button.button_schema(icon=ICON_RESTART, entity_category=ENTITY_CATEGORY_CONFIG)
|
||||||
|
.extend({cv.GenerateID(): cv.declare_id(RestartButton)})
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await button.register_button(var, config)
|
20
esphome/components/restart/button/restart_button.cpp
Normal file
20
esphome/components/restart/button/restart_button.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "restart_button.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace restart {
|
||||||
|
|
||||||
|
static const char *const TAG = "restart.button";
|
||||||
|
|
||||||
|
void RestartButton::press_action() {
|
||||||
|
ESP_LOGI(TAG, "Restarting device...");
|
||||||
|
// Let MQTT settle a bit
|
||||||
|
delay(100); // NOLINT
|
||||||
|
App.safe_reboot();
|
||||||
|
}
|
||||||
|
void RestartButton::dump_config() { LOG_BUTTON("", "Restart Button", this); }
|
||||||
|
|
||||||
|
} // namespace restart
|
||||||
|
} // namespace esphome
|
18
esphome/components/restart/button/restart_button.h
Normal file
18
esphome/components/restart/button/restart_button.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/button/button.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace restart {
|
||||||
|
|
||||||
|
class RestartButton : public button::Button, public Component {
|
||||||
|
public:
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void press_action() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace restart
|
||||||
|
} // namespace esphome
|
13
esphome/components/template/button/__init__.py
Normal file
13
esphome/components/template/button/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import button
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = button.BUTTON_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(button.Button),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
await button.new_button(config)
|
|
@ -198,6 +198,11 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) {
|
||||||
write_row(stream, obj, "switch", "<button>Toggle</button>");
|
write_row(stream, obj, "switch", "<button>Toggle</button>");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
for (auto *obj : App.get_buttons())
|
||||||
|
write_row(stream, obj, "button", "<button>Press</button>");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
for (auto *obj : App.get_binary_sensors())
|
for (auto *obj : App.get_binary_sensors())
|
||||||
if (this->include_internal_ || !obj->is_internal())
|
if (this->include_internal_ || !obj->is_internal())
|
||||||
|
@ -382,6 +387,26 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match) {
|
||||||
|
for (button::Button *obj : App.get_buttons()) {
|
||||||
|
if (obj->is_internal())
|
||||||
|
continue;
|
||||||
|
if (obj->get_object_id() != match.id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (request->method() == HTTP_POST && match.method == "press") {
|
||||||
|
this->defer([obj]() { obj->press(); });
|
||||||
|
request->send(200);
|
||||||
|
} else {
|
||||||
|
request->send(404);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
request->send(404);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
void WebServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) {
|
void WebServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) {
|
||||||
this->events_.send(this->binary_sensor_json(obj, state).c_str(), "state");
|
this->events_.send(this->binary_sensor_json(obj, state).c_str(), "state");
|
||||||
|
@ -715,6 +740,11 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) {
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
if (request->method() == HTTP_POST && match.domain == "button")
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
if (request->method() == HTTP_GET && match.domain == "binary_sensor")
|
if (request->method() == HTTP_GET && match.domain == "binary_sensor")
|
||||||
return true;
|
return true;
|
||||||
|
@ -787,6 +817,13 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
if (match.domain == "button") {
|
||||||
|
this->handle_button_request(request, match);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
if (match.domain == "binary_sensor") {
|
if (match.domain == "binary_sensor") {
|
||||||
this->handle_binary_sensor_request(request, match);
|
this->handle_binary_sensor_request(request, match);
|
||||||
|
|
|
@ -112,6 +112,11 @@ class WebServer : public Controller, public Component, public AsyncWebHandler {
|
||||||
std::string switch_json(switch_::Switch *obj, bool value);
|
std::string switch_json(switch_::Switch *obj, bool value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
/// Handle a button request under '/button/<id>/press'.
|
||||||
|
void handle_button_request(AsyncWebServerRequest *request, const UrlMatch &match);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
void on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) override;
|
void on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) override;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
#include "esphome/components/switch/switch.h"
|
#include "esphome/components/switch/switch.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
#include "esphome/components/button/button.h"
|
||||||
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
#include "esphome/components/text_sensor/text_sensor.h"
|
#include "esphome/components/text_sensor/text_sensor.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +70,10 @@ class Application {
|
||||||
void register_switch(switch_::Switch *a_switch) { this->switches_.push_back(a_switch); }
|
void register_switch(switch_::Switch *a_switch) { this->switches_.push_back(a_switch); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
void register_button(button::Button *button) { this->buttons_.push_back(button); }
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
void register_text_sensor(text_sensor::TextSensor *sensor) { this->text_sensors_.push_back(sensor); }
|
void register_text_sensor(text_sensor::TextSensor *sensor) { this->text_sensors_.push_back(sensor); }
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,6 +174,15 @@ class Application {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
const std::vector<button::Button *> &get_buttons() { return this->buttons_; }
|
||||||
|
button::Button *get_button_by_key(uint32_t key, bool include_internal = false) {
|
||||||
|
for (auto *obj : this->buttons_)
|
||||||
|
if (obj->get_object_id_hash() == key && (include_internal || !obj->is_internal()))
|
||||||
|
return obj;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
const std::vector<sensor::Sensor *> &get_sensors() { return this->sensors_; }
|
const std::vector<sensor::Sensor *> &get_sensors() { return this->sensors_; }
|
||||||
sensor::Sensor *get_sensor_by_key(uint32_t key, bool include_internal = false) {
|
sensor::Sensor *get_sensor_by_key(uint32_t key, bool include_internal = false) {
|
||||||
|
@ -260,6 +276,9 @@ class Application {
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
std::vector<switch_::Switch *> switches_{};
|
std::vector<switch_::Switch *> switches_{};
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
std::vector<button::Button *> buttons_{};
|
||||||
|
#endif
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
std::vector<sensor::Sensor *> sensors_{};
|
std::vector<sensor::Sensor *> sensors_{};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
#include "esphome/components/switch/switch.h"
|
#include "esphome/components/switch/switch.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
#include "esphome/components/button/button.h"
|
||||||
|
#endif
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
#include "esphome/components/climate/climate.h"
|
#include "esphome/components/climate/climate.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define USE_API_NOISE
|
#define USE_API_NOISE
|
||||||
#define USE_API_PLAINTEXT
|
#define USE_API_PLAINTEXT
|
||||||
#define USE_BINARY_SENSOR
|
#define USE_BINARY_SENSOR
|
||||||
|
#define USE_BUTTON
|
||||||
#define USE_CLIMATE
|
#define USE_CLIMATE
|
||||||
#define USE_COVER
|
#define USE_COVER
|
||||||
#define USE_DEEP_SLEEP
|
#define USE_DEEP_SLEEP
|
||||||
|
|
|
@ -603,6 +603,7 @@ def lint_inclusive_language(fname, match):
|
||||||
"esphome/components/switch/switch.h",
|
"esphome/components/switch/switch.h",
|
||||||
"esphome/components/text_sensor/text_sensor.h",
|
"esphome/components/text_sensor/text_sensor.h",
|
||||||
"esphome/components/climate/climate.h",
|
"esphome/components/climate/climate.h",
|
||||||
|
"esphome/components/button/button.h",
|
||||||
"esphome/core/component.h",
|
"esphome/core/component.h",
|
||||||
"esphome/core/gpio.h",
|
"esphome/core/gpio.h",
|
||||||
"esphome/core/log.h",
|
"esphome/core/log.h",
|
||||||
|
|
|
@ -520,3 +520,7 @@ xpt2046:
|
||||||
id(touchscreen).y_raw,
|
id(touchscreen).y_raw,
|
||||||
id(touchscreen).z_raw
|
id(touchscreen).z_raw
|
||||||
);
|
);
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: Restart Button
|
||||||
|
|
Loading…
Reference in a new issue