Add missing state attribute (#851)

* Add api missing_state attribute

Fixes https://github.com/esphome/issues/issues/828

Adds a new property for missing state, so that HA can now when a sensor does not have a state yet.

* Update api.proto
This commit is contained in:
Otto Winter 2019-11-12 18:58:26 +01:00 committed by GitHub
parent fad05d5a2e
commit fb055750df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 15 deletions

View file

@ -216,6 +216,9 @@ message BinarySensorStateResponse {
fixed32 key = 1; fixed32 key = 1;
bool state = 2; bool state = 2;
// If the binary sensor does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 3;
} }
// ==================== COVER ==================== // ==================== COVER ====================
@ -416,6 +419,9 @@ message SensorStateResponse {
fixed32 key = 1; fixed32 key = 1;
float state = 2; float state = 2;
// If the sensor does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 3;
} }
// ==================== SWITCH ==================== // ==================== SWITCH ====================
@ -472,6 +478,9 @@ message TextSensorStateResponse {
fixed32 key = 1; fixed32 key = 1;
string state = 2; string state = 2;
// If the text sensor does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 3;
} }
// ==================== SUBSCRIBE LOGS ==================== // ==================== SUBSCRIBE LOGS ====================

View file

@ -163,6 +163,7 @@ bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary
BinarySensorStateResponse resp; BinarySensorStateResponse resp;
resp.key = binary_sensor->get_object_id_hash(); resp.key = binary_sensor->get_object_id_hash();
resp.state = state; resp.state = state;
resp.missing_state = !binary_sensor->has_state();
return this->send_binary_sensor_state_response(resp); return this->send_binary_sensor_state_response(resp);
} }
bool APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) { bool APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
@ -362,6 +363,7 @@ bool APIConnection::send_sensor_state(sensor::Sensor *sensor, float state) {
SensorStateResponse resp{}; SensorStateResponse resp{};
resp.key = sensor->get_object_id_hash(); resp.key = sensor->get_object_id_hash();
resp.state = state; resp.state = state;
resp.missing_state = !sensor->has_state();
return this->send_sensor_state_response(resp); return this->send_sensor_state_response(resp);
} }
bool APIConnection::send_sensor_info(sensor::Sensor *sensor) { bool APIConnection::send_sensor_info(sensor::Sensor *sensor) {
@ -419,6 +421,7 @@ bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor,
TextSensorStateResponse resp{}; TextSensorStateResponse resp{};
resp.key = text_sensor->get_object_id_hash(); resp.key = text_sensor->get_object_id_hash();
resp.state = std::move(state); resp.state = std::move(state);
resp.missing_state = !text_sensor->has_state();
return this->send_text_sensor_state_response(resp); return this->send_text_sensor_state_response(resp);
} }
bool APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) { bool APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {

View file

@ -404,6 +404,10 @@ bool BinarySensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt val
this->state = value.as_bool(); this->state = value.as_bool();
return true; return true;
} }
case 3: {
this->missing_state = value.as_bool();
return true;
}
default: default:
return false; return false;
} }
@ -421,6 +425,7 @@ bool BinarySensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value
void BinarySensorStateResponse::encode(ProtoWriteBuffer buffer) const { void BinarySensorStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key); buffer.encode_fixed32(1, this->key);
buffer.encode_bool(2, this->state); buffer.encode_bool(2, this->state);
buffer.encode_bool(3, this->missing_state);
} }
void BinarySensorStateResponse::dump_to(std::string &out) const { void BinarySensorStateResponse::dump_to(std::string &out) const {
char buffer[64]; char buffer[64];
@ -433,6 +438,10 @@ void BinarySensorStateResponse::dump_to(std::string &out) const {
out.append(" state: "); out.append(" state: ");
out.append(YESNO(this->state)); out.append(YESNO(this->state));
out.append("\n"); out.append("\n");
out.append(" missing_state: ");
out.append(YESNO(this->missing_state));
out.append("\n");
out.append("}"); out.append("}");
} }
bool ListEntitiesCoverResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { bool ListEntitiesCoverResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
@ -1451,6 +1460,16 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const {
out.append("\n"); out.append("\n");
out.append("}"); out.append("}");
} }
bool SensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 3: {
this->missing_state = value.as_bool();
return true;
}
default:
return false;
}
}
bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) { bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
switch (field_id) { switch (field_id) {
case 1: { case 1: {
@ -1468,6 +1487,7 @@ bool SensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
void SensorStateResponse::encode(ProtoWriteBuffer buffer) const { void SensorStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key); buffer.encode_fixed32(1, this->key);
buffer.encode_float(2, this->state); buffer.encode_float(2, this->state);
buffer.encode_bool(3, this->missing_state);
} }
void SensorStateResponse::dump_to(std::string &out) const { void SensorStateResponse::dump_to(std::string &out) const {
char buffer[64]; char buffer[64];
@ -1481,6 +1501,10 @@ void SensorStateResponse::dump_to(std::string &out) const {
sprintf(buffer, "%g", this->state); sprintf(buffer, "%g", this->state);
out.append(buffer); out.append(buffer);
out.append("\n"); out.append("\n");
out.append(" missing_state: ");
out.append(YESNO(this->missing_state));
out.append("\n");
out.append("}"); out.append("}");
} }
bool ListEntitiesSwitchResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { bool ListEntitiesSwitchResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
@ -1700,6 +1724,16 @@ void ListEntitiesTextSensorResponse::dump_to(std::string &out) const {
out.append("\n"); out.append("\n");
out.append("}"); out.append("}");
} }
bool TextSensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
switch (field_id) {
case 3: {
this->missing_state = value.as_bool();
return true;
}
default:
return false;
}
}
bool TextSensorStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { bool TextSensorStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
switch (field_id) { switch (field_id) {
case 2: { case 2: {
@ -1723,6 +1757,7 @@ bool TextSensorStateResponse::decode_32bit(uint32_t field_id, Proto32Bit value)
void TextSensorStateResponse::encode(ProtoWriteBuffer buffer) const { void TextSensorStateResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_fixed32(1, this->key); buffer.encode_fixed32(1, this->key);
buffer.encode_string(2, this->state); buffer.encode_string(2, this->state);
buffer.encode_bool(3, this->missing_state);
} }
void TextSensorStateResponse::dump_to(std::string &out) const { void TextSensorStateResponse::dump_to(std::string &out) const {
char buffer[64]; char buffer[64];
@ -1735,6 +1770,10 @@ void TextSensorStateResponse::dump_to(std::string &out) const {
out.append(" state: "); out.append(" state: ");
out.append("'").append(this->state).append("'"); out.append("'").append(this->state).append("'");
out.append("\n"); out.append("\n");
out.append(" missing_state: ");
out.append(YESNO(this->missing_state));
out.append("\n");
out.append("}"); out.append("}");
} }
bool SubscribeLogsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { bool SubscribeLogsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {

View file

@ -188,8 +188,9 @@ class ListEntitiesBinarySensorResponse : public ProtoMessage {
}; };
class BinarySensorStateResponse : public ProtoMessage { class BinarySensorStateResponse : public ProtoMessage {
public: public:
uint32_t key{0}; // NOLINT uint32_t key{0}; // NOLINT
bool state{false}; // NOLINT bool state{false}; // NOLINT
bool missing_state{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;
@ -380,13 +381,15 @@ class ListEntitiesSensorResponse : public ProtoMessage {
}; };
class SensorStateResponse : public ProtoMessage { class SensorStateResponse : public ProtoMessage {
public: public:
uint32_t key{0}; // NOLINT uint32_t key{0}; // NOLINT
float state{0.0f}; // NOLINT float state{0.0f}; // NOLINT
bool missing_state{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;
protected: protected:
bool decode_32bit(uint32_t field_id, Proto32Bit value) override; bool decode_32bit(uint32_t field_id, Proto32Bit value) override;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
}; };
class ListEntitiesSwitchResponse : public ProtoMessage { class ListEntitiesSwitchResponse : public ProtoMessage {
public: public:
@ -442,14 +445,16 @@ class ListEntitiesTextSensorResponse : public ProtoMessage {
}; };
class TextSensorStateResponse : public ProtoMessage { class TextSensorStateResponse : public ProtoMessage {
public: public:
uint32_t key{0}; // NOLINT uint32_t key{0}; // NOLINT
std::string state{}; // NOLINT std::string state{}; // NOLINT
bool missing_state{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;
protected: protected:
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;
bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
}; };
class SubscribeLogsRequest : public ProtoMessage { class SubscribeLogsRequest : public ProtoMessage {
public: public:

View file

@ -7,9 +7,6 @@ namespace api {
#ifdef USE_BINARY_SENSOR #ifdef USE_BINARY_SENSOR
bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) { bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
if (!binary_sensor->has_state())
return true;
return this->client_->send_binary_sensor_state(binary_sensor, binary_sensor->state); return this->client_->send_binary_sensor_state(binary_sensor, binary_sensor->state);
} }
#endif #endif
@ -24,9 +21,6 @@ bool InitialStateIterator::on_light(light::LightState *light) { return this->cli
#endif #endif
#ifdef USE_SENSOR #ifdef USE_SENSOR
bool InitialStateIterator::on_sensor(sensor::Sensor *sensor) { bool InitialStateIterator::on_sensor(sensor::Sensor *sensor) {
if (!sensor->has_state())
return true;
return this->client_->send_sensor_state(sensor, sensor->state); return this->client_->send_sensor_state(sensor, sensor->state);
} }
#endif #endif
@ -37,9 +31,6 @@ bool InitialStateIterator::on_switch(switch_::Switch *a_switch) {
#endif #endif
#ifdef USE_TEXT_SENSOR #ifdef USE_TEXT_SENSOR
bool InitialStateIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) { bool InitialStateIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
if (!text_sensor->has_state())
return true;
return this->client_->send_text_sensor_state(text_sensor, text_sensor->state); return this->client_->send_text_sensor_state(text_sensor, text_sensor->state);
} }
#endif #endif