mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Add sensor force_update option (#783)
* Add sensor force_update option * Add test
This commit is contained in:
parent
d64a4ef2b4
commit
ae8700447e
8 changed files with 34 additions and 4 deletions
|
@ -406,6 +406,7 @@ message ListEntitiesSensorResponse {
|
||||||
string icon = 5;
|
string icon = 5;
|
||||||
string unit_of_measurement = 6;
|
string unit_of_measurement = 6;
|
||||||
int32 accuracy_decimals = 7;
|
int32 accuracy_decimals = 7;
|
||||||
|
bool force_update = 8;
|
||||||
}
|
}
|
||||||
message SensorStateResponse {
|
message SensorStateResponse {
|
||||||
option (id) = 25;
|
option (id) = 25;
|
||||||
|
|
|
@ -1359,6 +1359,10 @@ bool ListEntitiesSensorResponse::decode_varint(uint32_t field_id, ProtoVarInt va
|
||||||
this->accuracy_decimals = value.as_int32();
|
this->accuracy_decimals = value.as_int32();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case 8: {
|
||||||
|
this->force_update = value.as_bool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1407,6 +1411,7 @@ void ListEntitiesSensorResponse::encode(ProtoWriteBuffer buffer) const {
|
||||||
buffer.encode_string(5, this->icon);
|
buffer.encode_string(5, this->icon);
|
||||||
buffer.encode_string(6, this->unit_of_measurement);
|
buffer.encode_string(6, this->unit_of_measurement);
|
||||||
buffer.encode_int32(7, this->accuracy_decimals);
|
buffer.encode_int32(7, this->accuracy_decimals);
|
||||||
|
buffer.encode_bool(8, this->force_update);
|
||||||
}
|
}
|
||||||
void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
|
@ -1440,6 +1445,10 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
||||||
sprintf(buffer, "%d", this->accuracy_decimals);
|
sprintf(buffer, "%d", this->accuracy_decimals);
|
||||||
out.append(buffer);
|
out.append(buffer);
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" force_update: ");
|
||||||
|
out.append(YESNO(this->force_update));
|
||||||
|
out.append("\n");
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||||
|
|
|
@ -364,6 +364,7 @@ class ListEntitiesSensorResponse : public ProtoMessage {
|
||||||
std::string icon{}; // NOLINT
|
std::string icon{}; // NOLINT
|
||||||
std::string unit_of_measurement{}; // NOLINT
|
std::string unit_of_measurement{}; // NOLINT
|
||||||
int32_t accuracy_decimals{0}; // NOLINT
|
int32_t accuracy_decimals{0}; // NOLINT
|
||||||
|
bool force_update{false}; // NOLINT
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void dump_to(std::string &out) const override;
|
void dump_to(std::string &out) const override;
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo
|
||||||
if (!this->sensor_->get_icon().empty())
|
if (!this->sensor_->get_icon().empty())
|
||||||
root["icon"] = this->sensor_->get_icon();
|
root["icon"] = this->sensor_->get_icon();
|
||||||
|
|
||||||
|
if (this->sensor_->get_force_update())
|
||||||
|
root["force_update"] = true;
|
||||||
|
|
||||||
config.command_topic = false;
|
config.command_topic = false;
|
||||||
}
|
}
|
||||||
bool MQTTSensorComponent::send_initial_state() {
|
bool MQTTSensorComponent::send_initial_state() {
|
||||||
|
|
|
@ -6,10 +6,9 @@ from esphome import automation
|
||||||
from esphome.components import mqtt
|
from esphome.components import mqtt
|
||||||
from esphome.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
|
from esphome.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
|
||||||
CONF_EXPIRE_AFTER, CONF_FILTERS, CONF_FROM, CONF_ICON, CONF_ID, CONF_INTERNAL, \
|
CONF_EXPIRE_AFTER, CONF_FILTERS, CONF_FROM, CONF_ICON, CONF_ID, CONF_INTERNAL, \
|
||||||
CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, \
|
CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, CONF_SEND_EVERY, CONF_SEND_FIRST_AT, \
|
||||||
CONF_SEND_EVERY, CONF_SEND_FIRST_AT, CONF_TO, CONF_TRIGGER_ID, \
|
CONF_TO, CONF_TRIGGER_ID, CONF_UNIT_OF_MEASUREMENT, CONF_WINDOW_SIZE, CONF_NAME, CONF_MQTT_ID, \
|
||||||
CONF_UNIT_OF_MEASUREMENT, \
|
CONF_FORCE_UPDATE
|
||||||
CONF_WINDOW_SIZE, CONF_NAME, CONF_MQTT_ID
|
|
||||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||||
from esphome.util import Registry
|
from esphome.util import Registry
|
||||||
|
|
||||||
|
@ -87,6 +86,7 @@ SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
|
||||||
cv.Optional(CONF_UNIT_OF_MEASUREMENT): unit_of_measurement,
|
cv.Optional(CONF_UNIT_OF_MEASUREMENT): unit_of_measurement,
|
||||||
cv.Optional(CONF_ICON): icon,
|
cv.Optional(CONF_ICON): icon,
|
||||||
cv.Optional(CONF_ACCURACY_DECIMALS): accuracy_decimals,
|
cv.Optional(CONF_ACCURACY_DECIMALS): accuracy_decimals,
|
||||||
|
cv.Optional(CONF_FORCE_UPDATE, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_EXPIRE_AFTER): cv.All(cv.requires_component('mqtt'),
|
cv.Optional(CONF_EXPIRE_AFTER): cv.All(cv.requires_component('mqtt'),
|
||||||
cv.Any(None, cv.positive_time_period_milliseconds)),
|
cv.Any(None, cv.positive_time_period_milliseconds)),
|
||||||
cv.Optional(CONF_FILTERS): validate_filters,
|
cv.Optional(CONF_FILTERS): validate_filters,
|
||||||
|
@ -258,6 +258,7 @@ def setup_sensor_core_(var, config):
|
||||||
cg.add(var.set_icon(config[CONF_ICON]))
|
cg.add(var.set_icon(config[CONF_ICON]))
|
||||||
if CONF_ACCURACY_DECIMALS in config:
|
if CONF_ACCURACY_DECIMALS in config:
|
||||||
cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
|
cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
|
||||||
|
cg.add(var.set_force_update(config[CONF_FORCE_UPDATE]))
|
||||||
if CONF_FILTERS in config:
|
if CONF_FILTERS in config:
|
||||||
filters = yield build_filters(config[CONF_FILTERS])
|
filters = yield build_filters(config[CONF_FILTERS])
|
||||||
cg.add(var.set_filters(filters))
|
cg.add(var.set_filters(filters))
|
||||||
|
|
|
@ -18,6 +18,9 @@ namespace sensor {
|
||||||
if (!obj->unique_id().empty()) { \
|
if (!obj->unique_id().empty()) { \
|
||||||
ESP_LOGV(TAG, prefix " Unique ID: '%s'", obj->unique_id().c_str()); \
|
ESP_LOGV(TAG, prefix " Unique ID: '%s'", obj->unique_id().c_str()); \
|
||||||
} \
|
} \
|
||||||
|
if (obj->get_force_update()) { \
|
||||||
|
ESP_LOGV(TAG, prefix " Force Update: YES"); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Base-class for all sensors.
|
/** Base-class for all sensors.
|
||||||
|
@ -142,6 +145,15 @@ class Sensor : public Nameable {
|
||||||
|
|
||||||
void internal_send_state_to_frontend(float state);
|
void internal_send_state_to_frontend(float state);
|
||||||
|
|
||||||
|
bool get_force_update() const { return force_update_; }
|
||||||
|
/** Set this sensor's force_update mode.
|
||||||
|
*
|
||||||
|
* If the sensor is in force_update mode, the frontend is required to save all
|
||||||
|
* state changes to the database when they are published, even if the state is the
|
||||||
|
* same as before.
|
||||||
|
*/
|
||||||
|
void set_force_update(bool force_update) { force_update_ = force_update; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Override this to set the Home Assistant unit of measurement for this sensor.
|
/** Override this to set the Home Assistant unit of measurement for this sensor.
|
||||||
*
|
*
|
||||||
|
@ -174,6 +186,7 @@ class Sensor : public Nameable {
|
||||||
optional<int8_t> accuracy_decimals_;
|
optional<int8_t> accuracy_decimals_;
|
||||||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||||
bool has_state_{false};
|
bool has_state_{false};
|
||||||
|
bool force_update_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
class PollingSensorComponent : public PollingComponent, public Sensor {
|
class PollingSensorComponent : public PollingComponent, public Sensor {
|
||||||
|
|
|
@ -156,6 +156,7 @@ CONF_FILTERS = 'filters'
|
||||||
CONF_FILTER_OUT = 'filter_out'
|
CONF_FILTER_OUT = 'filter_out'
|
||||||
CONF_FLASH_LENGTH = 'flash_length'
|
CONF_FLASH_LENGTH = 'flash_length'
|
||||||
CONF_FOR = 'for'
|
CONF_FOR = 'for'
|
||||||
|
CONF_FORCE_UPDATE = 'force_update'
|
||||||
CONF_FORMALDEHYDE = 'formaldehyde'
|
CONF_FORMALDEHYDE = 'formaldehyde'
|
||||||
CONF_FORMAT = 'format'
|
CONF_FORMAT = 'format'
|
||||||
CONF_FREQUENCY = 'frequency'
|
CONF_FREQUENCY = 'frequency'
|
||||||
|
|
|
@ -185,6 +185,7 @@ sensor:
|
||||||
accuracy_decimals: 5
|
accuracy_decimals: 5
|
||||||
expire_after: 120s
|
expire_after: 120s
|
||||||
setup_priority: -100
|
setup_priority: -100
|
||||||
|
force_update: true
|
||||||
filters:
|
filters:
|
||||||
- offset: 2.0
|
- offset: 2.0
|
||||||
- multiply: 1.2
|
- multiply: 1.2
|
||||||
|
|
Loading…
Reference in a new issue