mirror of
https://github.com/esphome/esphome.git
synced 2024-11-28 17:54:13 +01:00
Add device class support to Switch (#3012)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
parent
21803607e7
commit
e7864a28a1
9 changed files with 49 additions and 1 deletions
|
@ -529,6 +529,7 @@ message ListEntitiesSwitchResponse {
|
||||||
bool assumed_state = 6;
|
bool assumed_state = 6;
|
||||||
bool disabled_by_default = 7;
|
bool disabled_by_default = 7;
|
||||||
EntityCategory entity_category = 8;
|
EntityCategory entity_category = 8;
|
||||||
|
string device_class = 9;
|
||||||
}
|
}
|
||||||
message SwitchStateResponse {
|
message SwitchStateResponse {
|
||||||
option (id) = 26;
|
option (id) = 26;
|
||||||
|
|
|
@ -462,6 +462,7 @@ bool APIConnection::send_switch_info(switch_::Switch *a_switch) {
|
||||||
msg.assumed_state = a_switch->assumed_state();
|
msg.assumed_state = a_switch->assumed_state();
|
||||||
msg.disabled_by_default = a_switch->is_disabled_by_default();
|
msg.disabled_by_default = a_switch->is_disabled_by_default();
|
||||||
msg.entity_category = static_cast<enums::EntityCategory>(a_switch->get_entity_category());
|
msg.entity_category = static_cast<enums::EntityCategory>(a_switch->get_entity_category());
|
||||||
|
msg.device_class = a_switch->get_device_class();
|
||||||
return this->send_list_entities_switch_response(msg);
|
return this->send_list_entities_switch_response(msg);
|
||||||
}
|
}
|
||||||
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
||||||
|
|
|
@ -2177,6 +2177,10 @@ bool ListEntitiesSwitchResponse::decode_length(uint32_t field_id, ProtoLengthDel
|
||||||
this->icon = value.as_string();
|
this->icon = value.as_string();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case 9: {
|
||||||
|
this->device_class = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2200,6 +2204,7 @@ void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer buffer) const {
|
||||||
buffer.encode_bool(6, this->assumed_state);
|
buffer.encode_bool(6, this->assumed_state);
|
||||||
buffer.encode_bool(7, this->disabled_by_default);
|
buffer.encode_bool(7, this->disabled_by_default);
|
||||||
buffer.encode_enum<enums::EntityCategory>(8, this->entity_category);
|
buffer.encode_enum<enums::EntityCategory>(8, this->entity_category);
|
||||||
|
buffer.encode_string(9, this->device_class);
|
||||||
}
|
}
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
void ListEntitiesSwitchResponse::dump_to(std::string &out) const {
|
void ListEntitiesSwitchResponse::dump_to(std::string &out) const {
|
||||||
|
@ -2237,6 +2242,10 @@ void ListEntitiesSwitchResponse::dump_to(std::string &out) const {
|
||||||
out.append(" entity_category: ");
|
out.append(" entity_category: ");
|
||||||
out.append(proto_enum_to_string<enums::EntityCategory>(this->entity_category));
|
out.append(proto_enum_to_string<enums::EntityCategory>(this->entity_category));
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" device_class: ");
|
||||||
|
out.append("'").append(this->device_class).append("'");
|
||||||
|
out.append("\n");
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -580,6 +580,7 @@ class ListEntitiesSwitchResponse : public ProtoMessage {
|
||||||
bool assumed_state{false};
|
bool assumed_state{false};
|
||||||
bool disabled_by_default{false};
|
bool disabled_by_default{false};
|
||||||
enums::EntityCategory entity_category{};
|
enums::EntityCategory entity_category{};
|
||||||
|
std::string device_class{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
void dump_to(std::string &out) const override;
|
void dump_to(std::string &out) const override;
|
||||||
|
|
|
@ -4,18 +4,27 @@ from esphome import automation
|
||||||
from esphome.automation import Condition, maybe_simple_id
|
from esphome.automation import Condition, maybe_simple_id
|
||||||
from esphome.components import mqtt
|
from esphome.components import mqtt
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
|
CONF_DEVICE_CLASS,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_INVERTED,
|
CONF_INVERTED,
|
||||||
|
CONF_MQTT_ID,
|
||||||
CONF_ON_TURN_OFF,
|
CONF_ON_TURN_OFF,
|
||||||
CONF_ON_TURN_ON,
|
CONF_ON_TURN_ON,
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
CONF_MQTT_ID,
|
DEVICE_CLASS_EMPTY,
|
||||||
|
DEVICE_CLASS_OUTLET,
|
||||||
|
DEVICE_CLASS_SWITCH,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
from esphome.cpp_helpers import setup_entity
|
from esphome.cpp_helpers import setup_entity
|
||||||
|
|
||||||
CODEOWNERS = ["@esphome/core"]
|
CODEOWNERS = ["@esphome/core"]
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
DEVICE_CLASSES = [
|
||||||
|
DEVICE_CLASS_EMPTY,
|
||||||
|
DEVICE_CLASS_OUTLET,
|
||||||
|
DEVICE_CLASS_SWITCH,
|
||||||
|
]
|
||||||
|
|
||||||
switch_ns = cg.esphome_ns.namespace("switch_")
|
switch_ns = cg.esphome_ns.namespace("switch_")
|
||||||
Switch = switch_ns.class_("Switch", cg.EntityBase)
|
Switch = switch_ns.class_("Switch", cg.EntityBase)
|
||||||
|
@ -51,6 +60,7 @@ SWITCH_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).e
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SwitchTurnOffTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SwitchTurnOffTrigger),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_DEVICE_CLASS): cv.one_of(*DEVICE_CLASSES, lower=True),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -71,6 +81,9 @@ async def setup_switch_core_(var, config):
|
||||||
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
||||||
await mqtt.register_mqtt_component(mqtt_, config)
|
await mqtt.register_mqtt_component(mqtt_, config)
|
||||||
|
|
||||||
|
if CONF_DEVICE_CLASS in config:
|
||||||
|
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||||
|
|
||||||
|
|
||||||
async def register_switch(var, config):
|
async def register_switch(var, config):
|
||||||
if not CORE.has_id(config[CONF_ID]):
|
if not CORE.has_id(config[CONF_ID]):
|
||||||
|
|
|
@ -46,5 +46,12 @@ void Switch::set_inverted(bool inverted) { this->inverted_ = inverted; }
|
||||||
uint32_t Switch::hash_base() { return 3129890955UL; }
|
uint32_t Switch::hash_base() { return 3129890955UL; }
|
||||||
bool Switch::is_inverted() const { return this->inverted_; }
|
bool Switch::is_inverted() const { return this->inverted_; }
|
||||||
|
|
||||||
|
std::string Switch::get_device_class() {
|
||||||
|
if (this->device_class_.has_value())
|
||||||
|
return *this->device_class_;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
void Switch::set_device_class(const std::string &device_class) { this->device_class_ = device_class; }
|
||||||
|
|
||||||
} // namespace switch_
|
} // namespace switch_
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -20,6 +20,9 @@ namespace switch_ {
|
||||||
if ((obj)->is_inverted()) { \
|
if ((obj)->is_inverted()) { \
|
||||||
ESP_LOGCONFIG(TAG, "%s Inverted: YES", prefix); \
|
ESP_LOGCONFIG(TAG, "%s Inverted: YES", prefix); \
|
||||||
} \
|
} \
|
||||||
|
if (!(obj)->get_device_class().empty()) { \
|
||||||
|
ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, (obj)->get_device_class().c_str()); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Base class for all switches.
|
/** Base class for all switches.
|
||||||
|
@ -88,6 +91,11 @@ class Switch : public EntityBase {
|
||||||
|
|
||||||
bool is_inverted() const;
|
bool is_inverted() const;
|
||||||
|
|
||||||
|
/// Get the device class for this switch.
|
||||||
|
std::string get_device_class();
|
||||||
|
/// Set the Home Assistant device class for this switch.
|
||||||
|
void set_device_class(const std::string &device_class);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Write the given state to hardware. You should implement this
|
/** Write the given state to hardware. You should implement this
|
||||||
* abstract method if you want to create your own switch.
|
* abstract method if you want to create your own switch.
|
||||||
|
@ -105,6 +113,7 @@ class Switch : public EntityBase {
|
||||||
bool inverted_{false};
|
bool inverted_{false};
|
||||||
Deduplicator<bool> publish_dedup_;
|
Deduplicator<bool> publish_dedup_;
|
||||||
ESPPreferenceObject rtc_;
|
ESPPreferenceObject rtc_;
|
||||||
|
optional<std::string> device_class_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace switch_
|
} // namespace switch_
|
||||||
|
|
|
@ -920,6 +920,9 @@ DEVICE_CLASS_VOLTAGE = "voltage"
|
||||||
DEVICE_CLASS_UPDATE = "update"
|
DEVICE_CLASS_UPDATE = "update"
|
||||||
# device classes of button component
|
# device classes of button component
|
||||||
DEVICE_CLASS_RESTART = "restart"
|
DEVICE_CLASS_RESTART = "restart"
|
||||||
|
# device classes of switch component
|
||||||
|
DEVICE_CLASS_OUTLET = "outlet"
|
||||||
|
DEVICE_CLASS_SWITCH = "switch"
|
||||||
|
|
||||||
|
|
||||||
# state classes
|
# state classes
|
||||||
|
|
|
@ -2037,6 +2037,10 @@ switch:
|
||||||
- platform: template
|
- platform: template
|
||||||
id: ble1_status
|
id: ble1_status
|
||||||
optimistic: true
|
optimistic: true
|
||||||
|
- platform: template
|
||||||
|
id: outlet_switch
|
||||||
|
optimistic: true
|
||||||
|
device_class: outlet
|
||||||
|
|
||||||
fan:
|
fan:
|
||||||
- platform: binary
|
- platform: binary
|
||||||
|
|
Loading…
Reference in a new issue