Implement unit_of_measurement for number component (#2804)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
puuu 2021-12-01 00:20:59 +09:00 committed by GitHub
parent b32b918936
commit b5a0e8b2c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 37 additions and 0 deletions

View File

@ -885,6 +885,7 @@ message ListEntitiesNumberResponse {
float step = 8; float step = 8;
bool disabled_by_default = 9; bool disabled_by_default = 9;
EntityCategory entity_category = 10; EntityCategory entity_category = 10;
string unit_of_measurement = 11;
} }
message NumberStateResponse { message NumberStateResponse {
option (id) = 50; option (id) = 50;

View File

@ -619,6 +619,7 @@ bool APIConnection::send_number_info(number::Number *number) {
msg.icon = number->get_icon(); msg.icon = number->get_icon();
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.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();

View File

@ -3780,6 +3780,10 @@ bool ListEntitiesNumberResponse::decode_length(uint32_t field_id, ProtoLengthDel
this->icon = value.as_string(); this->icon = value.as_string();
return true; return true;
} }
case 11: {
this->unit_of_measurement = value.as_string();
return true;
}
default: default:
return false; return false;
} }
@ -3817,6 +3821,7 @@ void ListEntitiesNumberResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_float(8, this->step); buffer.encode_float(8, this->step);
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);
} }
#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 {
@ -3865,6 +3870,10 @@ void ListEntitiesNumberResponse::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(" unit_of_measurement: ");
out.append("'").append(this->unit_of_measurement).append("'");
out.append("\n");
out.append("}"); out.append("}");
} }
#endif #endif

View File

@ -957,6 +957,7 @@ class ListEntitiesNumberResponse : public ProtoMessage {
float step{0.0f}; float step{0.0f};
bool disabled_by_default{false}; bool disabled_by_default{false};
enums::EntityCategory entity_category{}; enums::EntityCategory entity_category{};
std::string unit_of_measurement{};
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;

View File

@ -43,6 +43,8 @@ void MQTTNumberComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo
root[MQTT_MIN] = traits.get_min_value(); root[MQTT_MIN] = traits.get_min_value();
root[MQTT_MAX] = traits.get_max_value(); root[MQTT_MAX] = traits.get_max_value();
root[MQTT_STEP] = traits.get_step(); root[MQTT_STEP] = traits.get_step();
if (!this->number_->traits.get_unit_of_measurement().empty())
root[MQTT_UNIT_OF_MEASUREMENT] = this->number_->traits.get_unit_of_measurement();
config.command_topic = true; config.command_topic = true;
} }

View File

@ -10,6 +10,7 @@ from esphome.const import (
CONF_ON_VALUE, CONF_ON_VALUE,
CONF_ON_VALUE_RANGE, CONF_ON_VALUE_RANGE,
CONF_TRIGGER_ID, CONF_TRIGGER_ID,
CONF_UNIT_OF_MEASUREMENT,
CONF_MQTT_ID, CONF_MQTT_ID,
CONF_VALUE, CONF_VALUE,
) )
@ -58,6 +59,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,
} }
) )
@ -86,6 +88,8 @@ async def setup_number_core_(
cg.add(trigger.set_max(template_)) cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf) await automation.build_automation(trigger, [(float, "x")], conf)
if CONF_UNIT_OF_MEASUREMENT in config:
cg.add(var.traits.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
if CONF_MQTT_ID in config: if CONF_MQTT_ID in 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)

View File

@ -41,6 +41,15 @@ void Number::add_on_state_callback(std::function<void(float)> &&callback) {
this->state_callback_.add(std::move(callback)); this->state_callback_.add(std::move(callback));
} }
std::string NumberTraits::get_unit_of_measurement() {
if (this->unit_of_measurement_.has_value())
return *this->unit_of_measurement_;
return "";
}
void NumberTraits::set_unit_of_measurement(const std::string &unit_of_measurement) {
this->unit_of_measurement_ = unit_of_measurement;
}
uint32_t Number::hash_base() { return 2282307003UL; } uint32_t Number::hash_base() { return 2282307003UL; }
} // namespace number } // namespace number

View File

@ -13,6 +13,9 @@ namespace number {
if (!(obj)->get_icon().empty()) { \ if (!(obj)->get_icon().empty()) { \
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \ ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \
} \ } \
if (!(obj)->traits.get_unit_of_measurement().empty()) { \
ESP_LOGCONFIG(TAG, "%s Unit of Measurement: '%s'", prefix, (obj)->traits.get_unit_of_measurement().c_str()); \
} \
} }
class Number; class Number;
@ -42,10 +45,16 @@ class NumberTraits {
void set_step(float step) { step_ = step; } void set_step(float step) { step_ = step; }
float get_step() const { return step_; } float get_step() const { return step_; }
/// Get the unit of measurement, using the manual override if set.
std::string get_unit_of_measurement();
/// Manually set the unit of measurement.
void set_unit_of_measurement(const std::string &unit_of_measurement);
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
}; };
/** Base-class for all numbers. /** Base-class for all numbers.

View File

@ -97,6 +97,7 @@ number:
max_value: 100 max_value: 100
min_value: 0 min_value: 0
step: 5 step: 5
unit_of_measurement: '%'
select: select:
- platform: template - platform: template