mirror of
https://github.com/esphome/esphome.git
synced 2025-01-03 11:21:43 +01:00
Number mode (#2838)
This commit is contained in:
parent
b5a0e8b2c0
commit
d9513e5ff2
9 changed files with 70 additions and 1 deletions
|
@ -869,6 +869,11 @@ message ClimateCommandRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== NUMBER ====================
|
// ==================== NUMBER ====================
|
||||||
|
enum NumberMode {
|
||||||
|
NUMBER_MODE_AUTO = 0;
|
||||||
|
NUMBER_MODE_BOX = 1;
|
||||||
|
NUMBER_MODE_SLIDER = 2;
|
||||||
|
}
|
||||||
message ListEntitiesNumberResponse {
|
message ListEntitiesNumberResponse {
|
||||||
option (id) = 49;
|
option (id) = 49;
|
||||||
option (source) = SOURCE_SERVER;
|
option (source) = SOURCE_SERVER;
|
||||||
|
@ -886,6 +891,7 @@ message ListEntitiesNumberResponse {
|
||||||
bool disabled_by_default = 9;
|
bool disabled_by_default = 9;
|
||||||
EntityCategory entity_category = 10;
|
EntityCategory entity_category = 10;
|
||||||
string unit_of_measurement = 11;
|
string unit_of_measurement = 11;
|
||||||
|
NumberMode mode = 12;
|
||||||
}
|
}
|
||||||
message NumberStateResponse {
|
message NumberStateResponse {
|
||||||
option (id) = 50;
|
option (id) = 50;
|
||||||
|
|
|
@ -620,6 +620,7 @@ bool APIConnection::send_number_info(number::Number *number) {
|
||||||
msg.disabled_by_default = number->is_disabled_by_default();
|
msg.disabled_by_default = number->is_disabled_by_default();
|
||||||
msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category());
|
msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category());
|
||||||
msg.unit_of_measurement = number->traits.get_unit_of_measurement();
|
msg.unit_of_measurement = number->traits.get_unit_of_measurement();
|
||||||
|
msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
|
||||||
|
|
||||||
msg.min_value = number->traits.get_min_value();
|
msg.min_value = number->traits.get_min_value();
|
||||||
msg.max_value = number->traits.get_max_value();
|
msg.max_value = number->traits.get_max_value();
|
||||||
|
|
|
@ -266,6 +266,18 @@ template<> const char *proto_enum_to_string<enums::ClimatePreset>(enums::Climate
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template<> const char *proto_enum_to_string<enums::NumberMode>(enums::NumberMode value) {
|
||||||
|
switch (value) {
|
||||||
|
case enums::NUMBER_MODE_AUTO:
|
||||||
|
return "NUMBER_MODE_AUTO";
|
||||||
|
case enums::NUMBER_MODE_BOX:
|
||||||
|
return "NUMBER_MODE_BOX";
|
||||||
|
case enums::NUMBER_MODE_SLIDER:
|
||||||
|
return "NUMBER_MODE_SLIDER";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||||
switch (field_id) {
|
switch (field_id) {
|
||||||
case 1: {
|
case 1: {
|
||||||
|
@ -3758,6 +3770,10 @@ bool ListEntitiesNumberResponse::decode_varint(uint32_t field_id, ProtoVarInt va
|
||||||
this->entity_category = value.as_enum<enums::EntityCategory>();
|
this->entity_category = value.as_enum<enums::EntityCategory>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case 12: {
|
||||||
|
this->mode = value.as_enum<enums::NumberMode>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3822,6 +3838,7 @@ void ListEntitiesNumberResponse::encode(ProtoWriteBuffer buffer) const {
|
||||||
buffer.encode_bool(9, this->disabled_by_default);
|
buffer.encode_bool(9, this->disabled_by_default);
|
||||||
buffer.encode_enum<enums::EntityCategory>(10, this->entity_category);
|
buffer.encode_enum<enums::EntityCategory>(10, this->entity_category);
|
||||||
buffer.encode_string(11, this->unit_of_measurement);
|
buffer.encode_string(11, this->unit_of_measurement);
|
||||||
|
buffer.encode_enum<enums::NumberMode>(12, this->mode);
|
||||||
}
|
}
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
void ListEntitiesNumberResponse::dump_to(std::string &out) const {
|
void ListEntitiesNumberResponse::dump_to(std::string &out) const {
|
||||||
|
@ -3874,6 +3891,10 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const {
|
||||||
out.append(" unit_of_measurement: ");
|
out.append(" unit_of_measurement: ");
|
||||||
out.append("'").append(this->unit_of_measurement).append("'");
|
out.append("'").append(this->unit_of_measurement).append("'");
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" mode: ");
|
||||||
|
out.append(proto_enum_to_string<enums::NumberMode>(this->mode));
|
||||||
|
out.append("\n");
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -123,6 +123,11 @@ enum ClimatePreset : uint32_t {
|
||||||
CLIMATE_PRESET_SLEEP = 6,
|
CLIMATE_PRESET_SLEEP = 6,
|
||||||
CLIMATE_PRESET_ACTIVITY = 7,
|
CLIMATE_PRESET_ACTIVITY = 7,
|
||||||
};
|
};
|
||||||
|
enum NumberMode : uint32_t {
|
||||||
|
NUMBER_MODE_AUTO = 0,
|
||||||
|
NUMBER_MODE_BOX = 1,
|
||||||
|
NUMBER_MODE_SLIDER = 2,
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace enums
|
} // namespace enums
|
||||||
|
|
||||||
|
@ -958,6 +963,7 @@ class ListEntitiesNumberResponse : public ProtoMessage {
|
||||||
bool disabled_by_default{false};
|
bool disabled_by_default{false};
|
||||||
enums::EntityCategory entity_category{};
|
enums::EntityCategory entity_category{};
|
||||||
std::string unit_of_measurement{};
|
std::string unit_of_measurement{};
|
||||||
|
enums::NumberMode mode{};
|
||||||
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;
|
||||||
|
|
|
@ -514,6 +514,7 @@ constexpr const char *const MQTT_DEVICE_SUGGESTED_AREA = "suggested_area";
|
||||||
|
|
||||||
// Additional MQTT fields where no abbreviation is defined in HA source
|
// Additional MQTT fields where no abbreviation is defined in HA source
|
||||||
constexpr const char *const MQTT_ENTITY_CATEGORY = "entity_category";
|
constexpr const char *const MQTT_ENTITY_CATEGORY = "entity_category";
|
||||||
|
constexpr const char *const MQTT_MODE = "mode";
|
||||||
|
|
||||||
} // namespace mqtt
|
} // namespace mqtt
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -45,6 +45,16 @@ void MQTTNumberComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo
|
||||||
root[MQTT_STEP] = traits.get_step();
|
root[MQTT_STEP] = traits.get_step();
|
||||||
if (!this->number_->traits.get_unit_of_measurement().empty())
|
if (!this->number_->traits.get_unit_of_measurement().empty())
|
||||||
root[MQTT_UNIT_OF_MEASUREMENT] = this->number_->traits.get_unit_of_measurement();
|
root[MQTT_UNIT_OF_MEASUREMENT] = this->number_->traits.get_unit_of_measurement();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
config.command_topic = true;
|
config.command_topic = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ from esphome.const import (
|
||||||
CONF_ABOVE,
|
CONF_ABOVE,
|
||||||
CONF_BELOW,
|
CONF_BELOW,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
CONF_MODE,
|
||||||
CONF_ON_VALUE,
|
CONF_ON_VALUE,
|
||||||
CONF_ON_VALUE_RANGE,
|
CONF_ON_VALUE_RANGE,
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
|
@ -40,6 +41,14 @@ NumberInRangeCondition = number_ns.class_(
|
||||||
"NumberInRangeCondition", automation.Condition
|
"NumberInRangeCondition", automation.Condition
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NumberMode = number_ns.enum("NumberMode")
|
||||||
|
|
||||||
|
NUMBER_MODES = {
|
||||||
|
"AUTO": NumberMode.NUMBER_MODE_AUTO,
|
||||||
|
"BOX": NumberMode.NUMBER_MODE_BOX,
|
||||||
|
"SLIDER": NumberMode.NUMBER_MODE_SLIDER,
|
||||||
|
}
|
||||||
|
|
||||||
icon = cv.icon
|
icon = cv.icon
|
||||||
|
|
||||||
NUMBER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
NUMBER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||||
|
@ -60,6 +69,7 @@ NUMBER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).e
|
||||||
cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW),
|
cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW),
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
|
cv.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
|
||||||
|
cv.Optional(CONF_MODE, default="AUTO"): cv.enum(NUMBER_MODES, upper=True),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,6 +84,8 @@ async def setup_number_core_(
|
||||||
if step is not None:
|
if step is not None:
|
||||||
cg.add(var.traits.set_step(step))
|
cg.add(var.traits.set_step(step))
|
||||||
|
|
||||||
|
cg.add(var.traits.set_mode(config[CONF_MODE]))
|
||||||
|
|
||||||
for conf in config.get(CONF_ON_VALUE, []):
|
for conf in config.get(CONF_ON_VALUE, []):
|
||||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
await automation.build_automation(trigger, [(float, "x")], conf)
|
await automation.build_automation(trigger, [(float, "x")], conf)
|
||||||
|
|
|
@ -36,6 +36,12 @@ class NumberCall {
|
||||||
optional<float> value_;
|
optional<float> value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum NumberMode : uint8_t {
|
||||||
|
NUMBER_MODE_AUTO = 0,
|
||||||
|
NUMBER_MODE_BOX = 1,
|
||||||
|
NUMBER_MODE_SLIDER = 2,
|
||||||
|
};
|
||||||
|
|
||||||
class NumberTraits {
|
class NumberTraits {
|
||||||
public:
|
public:
|
||||||
void set_min_value(float min_value) { min_value_ = min_value; }
|
void set_min_value(float min_value) { min_value_ = min_value; }
|
||||||
|
@ -50,11 +56,16 @@ class NumberTraits {
|
||||||
/// Manually set the unit of measurement.
|
/// Manually set the unit of measurement.
|
||||||
void set_unit_of_measurement(const std::string &unit_of_measurement);
|
void set_unit_of_measurement(const std::string &unit_of_measurement);
|
||||||
|
|
||||||
|
// Get/set the frontend mode.
|
||||||
|
NumberMode get_mode() const { return this->mode_; }
|
||||||
|
void set_mode(NumberMode mode) { this->mode_ = mode; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float min_value_ = NAN;
|
float min_value_ = NAN;
|
||||||
float max_value_ = NAN;
|
float max_value_ = NAN;
|
||||||
float step_ = NAN;
|
float step_ = NAN;
|
||||||
optional<std::string> unit_of_measurement_; ///< Unit of measurement override
|
optional<std::string> unit_of_measurement_; ///< Unit of measurement override
|
||||||
|
NumberMode mode_{NUMBER_MODE_AUTO};
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Base-class for all numbers.
|
/** Base-class for all numbers.
|
||||||
|
|
|
@ -98,6 +98,7 @@ number:
|
||||||
min_value: 0
|
min_value: 0
|
||||||
step: 5
|
step: 5
|
||||||
unit_of_measurement: '%'
|
unit_of_measurement: '%'
|
||||||
|
mode: slider
|
||||||
|
|
||||||
select:
|
select:
|
||||||
- platform: template
|
- platform: template
|
||||||
|
|
Loading…
Reference in a new issue