mirror of
https://github.com/esphome/esphome.git
synced 2026-05-30 23:54:04 +08:00
[packet_transport] Use FixedVector and parent pointer to enable inline Callback storage (#14946)
This commit is contained in:
@@ -177,13 +177,19 @@ async def register_packet_transport(var, config):
|
|||||||
cg.add(var.set_provider_encryption(name, hash_encryption_key(encryption)))
|
cg.add(var.set_provider_encryption(name, hash_encryption_key(encryption)))
|
||||||
|
|
||||||
is_provider = False
|
is_provider = False
|
||||||
for sens_conf in config.get(CONF_SENSORS, ()):
|
sensors = config.get(CONF_SENSORS, ())
|
||||||
|
binary_sensors = config.get(CONF_BINARY_SENSORS, ())
|
||||||
|
if sensors:
|
||||||
|
cg.add(var.set_sensor_count(len(sensors)))
|
||||||
|
if binary_sensors:
|
||||||
|
cg.add(var.set_binary_sensor_count(len(binary_sensors)))
|
||||||
|
for sens_conf in sensors:
|
||||||
is_provider = True
|
is_provider = True
|
||||||
sens_id = sens_conf[CONF_ID]
|
sens_id = sens_conf[CONF_ID]
|
||||||
sensor = await cg.get_variable(sens_id)
|
sensor = await cg.get_variable(sens_id)
|
||||||
bcst_id = sens_conf.get(CONF_BROADCAST_ID, sens_id.id)
|
bcst_id = sens_conf.get(CONF_BROADCAST_ID, sens_id.id)
|
||||||
cg.add(var.add_sensor(bcst_id, sensor))
|
cg.add(var.add_sensor(bcst_id, sensor))
|
||||||
for sens_conf in config.get(CONF_BINARY_SENSORS, ()):
|
for sens_conf in binary_sensors:
|
||||||
is_provider = True
|
is_provider = True
|
||||||
sens_id = sens_conf[CONF_ID]
|
sens_id = sens_conf[CONF_ID]
|
||||||
sensor = await cg.get_variable(sens_id)
|
sensor = await cg.get_variable(sens_id)
|
||||||
|
|||||||
@@ -221,16 +221,20 @@ void PacketTransport::setup() {
|
|||||||
}
|
}
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
for (auto &sensor : this->sensors_) {
|
for (auto &sensor : this->sensors_) {
|
||||||
sensor.sensor->add_on_state_callback([this, &sensor](float x) {
|
// [&sensor] is safe: sensor refers to a FixedVector element that never reallocates,
|
||||||
this->updated_ = true;
|
// so the reference remains valid for the component's lifetime.
|
||||||
|
sensor.sensor->add_on_state_callback([&sensor](float x) {
|
||||||
|
sensor.parent->updated_ = true;
|
||||||
sensor.updated = true;
|
sensor.updated = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
for (auto &sensor : this->binary_sensors_) {
|
for (auto &sensor : this->binary_sensors_) {
|
||||||
sensor.sensor->add_on_state_callback([this, &sensor](bool value) {
|
// [&sensor] is safe: sensor refers to a FixedVector element that never reallocates,
|
||||||
this->updated_ = true;
|
// so the reference remains valid for the component's lifetime.
|
||||||
|
sensor.sensor->add_on_state_callback([&sensor](bool value) {
|
||||||
|
sensor.parent->updated_ = true;
|
||||||
sensor.updated = true;
|
sensor.updated = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -548,11 +552,11 @@ void PacketTransport::dump_config() {
|
|||||||
" Ping-pong: %s",
|
" Ping-pong: %s",
|
||||||
this->platform_name_, YESNO(this->is_encrypted_()), YESNO(this->ping_pong_enable_));
|
this->platform_name_, YESNO(this->is_encrypted_()), YESNO(this->ping_pong_enable_));
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
for (auto sensor : this->sensors_)
|
for (const auto &sensor : this->sensors_)
|
||||||
ESP_LOGCONFIG(TAG, " Sensor: %s", sensor.id);
|
ESP_LOGCONFIG(TAG, " Sensor: %s", sensor.id);
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
for (auto sensor : this->binary_sensors_)
|
for (const auto &sensor : this->binary_sensors_)
|
||||||
ESP_LOGCONFIG(TAG, " Binary Sensor: %s", sensor.id);
|
ESP_LOGCONFIG(TAG, " Binary Sensor: %s", sensor.id);
|
||||||
#endif
|
#endif
|
||||||
for (const auto &host : this->providers_) {
|
for (const auto &host : this->providers_) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/preferences.h"
|
#include "esphome/core/preferences.h"
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
@@ -37,11 +38,14 @@ struct Provider {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PacketTransport;
|
||||||
|
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
struct Sensor {
|
struct Sensor {
|
||||||
sensor::Sensor *sensor;
|
sensor::Sensor *sensor;
|
||||||
const char *id;
|
const char *id;
|
||||||
bool updated;
|
bool updated;
|
||||||
|
PacketTransport *parent;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
@@ -49,6 +53,7 @@ struct BinarySensor {
|
|||||||
binary_sensor::BinarySensor *sensor;
|
binary_sensor::BinarySensor *sensor;
|
||||||
const char *id;
|
const char *id;
|
||||||
bool updated;
|
bool updated;
|
||||||
|
PacketTransport *parent;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -60,8 +65,9 @@ class PacketTransport : public PollingComponent {
|
|||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
|
void set_sensor_count(size_t count) { this->sensors_.init(count); }
|
||||||
void add_sensor(const char *id, sensor::Sensor *sensor) {
|
void add_sensor(const char *id, sensor::Sensor *sensor) {
|
||||||
Sensor st{sensor, id, true};
|
Sensor st{sensor, id, true, this};
|
||||||
this->sensors_.push_back(st);
|
this->sensors_.push_back(st);
|
||||||
}
|
}
|
||||||
void add_remote_sensor(const char *hostname, const char *remote_id, sensor::Sensor *sensor) {
|
void add_remote_sensor(const char *hostname, const char *remote_id, sensor::Sensor *sensor) {
|
||||||
@@ -70,8 +76,9 @@ class PacketTransport : public PollingComponent {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
void set_binary_sensor_count(size_t count) { this->binary_sensors_.init(count); }
|
||||||
void add_binary_sensor(const char *id, binary_sensor::BinarySensor *sensor) {
|
void add_binary_sensor(const char *id, binary_sensor::BinarySensor *sensor) {
|
||||||
BinarySensor st{sensor, id, true};
|
BinarySensor st{sensor, id, true, this};
|
||||||
this->binary_sensors_.push_back(st);
|
this->binary_sensors_.push_back(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,11 +148,11 @@ class PacketTransport : public PollingComponent {
|
|||||||
std::vector<uint8_t> encryption_key_{};
|
std::vector<uint8_t> encryption_key_{};
|
||||||
|
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
std::vector<Sensor> sensors_{};
|
FixedVector<Sensor> sensors_{};
|
||||||
string_map_t<string_map_t<sensor::Sensor *>> remote_sensors_{};
|
string_map_t<string_map_t<sensor::Sensor *>> remote_sensors_{};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
std::vector<BinarySensor> binary_sensors_{};
|
FixedVector<BinarySensor> binary_sensors_{};
|
||||||
string_map_t<string_map_t<binary_sensor::BinarySensor *>> remote_binary_sensors_{};
|
string_map_t<string_map_t<binary_sensor::BinarySensor *>> remote_binary_sensors_{};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace esphome::packet_transport::testing {
|
|||||||
TEST(PacketTransportBinarySensorTest, AddBinarySensor) {
|
TEST(PacketTransportBinarySensorTest, AddBinarySensor) {
|
||||||
TestablePacketTransport transport;
|
TestablePacketTransport transport;
|
||||||
binary_sensor::BinarySensor bs;
|
binary_sensor::BinarySensor bs;
|
||||||
|
transport.set_binary_sensor_count(1);
|
||||||
transport.add_binary_sensor("motion", &bs);
|
transport.add_binary_sensor("motion", &bs);
|
||||||
ASSERT_EQ(transport.binary_sensors_.size(), 1u);
|
ASSERT_EQ(transport.binary_sensors_.size(), 1u);
|
||||||
EXPECT_STREQ(transport.binary_sensors_[0].id, "motion");
|
EXPECT_STREQ(transport.binary_sensors_[0].id, "motion");
|
||||||
@@ -24,6 +25,7 @@ TEST(PacketTransportBinarySensorTest, UnencryptedBinarySensorRoundTrip) {
|
|||||||
encoder.init_for_test("sender");
|
encoder.init_for_test("sender");
|
||||||
binary_sensor::BinarySensor local_bs;
|
binary_sensor::BinarySensor local_bs;
|
||||||
local_bs.state = true;
|
local_bs.state = true;
|
||||||
|
encoder.set_binary_sensor_count(1);
|
||||||
encoder.add_binary_sensor("motion", &local_bs);
|
encoder.add_binary_sensor("motion", &local_bs);
|
||||||
|
|
||||||
encoder.send_data_(true);
|
encoder.send_data_(true);
|
||||||
@@ -46,11 +48,13 @@ TEST(PacketTransportBinarySensorTest, MultipleSensorsRoundTrip) {
|
|||||||
sensor::Sensor s1, s2;
|
sensor::Sensor s1, s2;
|
||||||
s1.state = 10.0f;
|
s1.state = 10.0f;
|
||||||
s2.state = 20.0f;
|
s2.state = 20.0f;
|
||||||
|
encoder.set_sensor_count(2);
|
||||||
encoder.add_sensor("s1", &s1);
|
encoder.add_sensor("s1", &s1);
|
||||||
encoder.add_sensor("s2", &s2);
|
encoder.add_sensor("s2", &s2);
|
||||||
|
|
||||||
binary_sensor::BinarySensor bs1;
|
binary_sensor::BinarySensor bs1;
|
||||||
bs1.state = true;
|
bs1.state = true;
|
||||||
|
encoder.set_binary_sensor_count(1);
|
||||||
encoder.add_binary_sensor("bs1", &bs1);
|
encoder.add_binary_sensor("bs1", &bs1);
|
||||||
|
|
||||||
encoder.send_data_(true);
|
encoder.send_data_(true);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace esphome::packet_transport::testing {
|
|||||||
TEST(PacketTransportSensorTest, AddSensor) {
|
TEST(PacketTransportSensorTest, AddSensor) {
|
||||||
TestablePacketTransport transport;
|
TestablePacketTransport transport;
|
||||||
sensor::Sensor s;
|
sensor::Sensor s;
|
||||||
|
transport.set_sensor_count(1);
|
||||||
transport.add_sensor("temp", &s);
|
transport.add_sensor("temp", &s);
|
||||||
ASSERT_EQ(transport.sensors_.size(), 1u);
|
ASSERT_EQ(transport.sensors_.size(), 1u);
|
||||||
EXPECT_STREQ(transport.sensors_[0].id, "temp");
|
EXPECT_STREQ(transport.sensors_[0].id, "temp");
|
||||||
@@ -26,6 +27,7 @@ TEST(PacketTransportSensorTest, UnencryptedSensorRoundTrip) {
|
|||||||
encoder.init_for_test("sender");
|
encoder.init_for_test("sender");
|
||||||
sensor::Sensor local_sensor;
|
sensor::Sensor local_sensor;
|
||||||
local_sensor.state = 42.5f;
|
local_sensor.state = 42.5f;
|
||||||
|
encoder.set_sensor_count(1);
|
||||||
encoder.add_sensor("temp", &local_sensor);
|
encoder.add_sensor("temp", &local_sensor);
|
||||||
|
|
||||||
encoder.send_data_(true);
|
encoder.send_data_(true);
|
||||||
@@ -53,6 +55,7 @@ TEST(PacketTransportSensorTest, EncryptedSensorRoundTrip) {
|
|||||||
encoder.set_encryption_key(key);
|
encoder.set_encryption_key(key);
|
||||||
sensor::Sensor local_sensor;
|
sensor::Sensor local_sensor;
|
||||||
local_sensor.state = 99.9f;
|
local_sensor.state = 99.9f;
|
||||||
|
encoder.set_sensor_count(1);
|
||||||
encoder.add_sensor("temp", &local_sensor);
|
encoder.add_sensor("temp", &local_sensor);
|
||||||
|
|
||||||
encoder.send_data_(true);
|
encoder.send_data_(true);
|
||||||
@@ -77,6 +80,7 @@ TEST(PacketTransportSensorTest, SendDataOnlyUpdated) {
|
|||||||
sensor::Sensor s1, s2;
|
sensor::Sensor s1, s2;
|
||||||
s1.state = 1.0f;
|
s1.state = 1.0f;
|
||||||
s2.state = 2.0f;
|
s2.state = 2.0f;
|
||||||
|
encoder.set_sensor_count(2);
|
||||||
encoder.add_sensor("s1", &s1);
|
encoder.add_sensor("s1", &s1);
|
||||||
encoder.add_sensor("s2", &s2);
|
encoder.add_sensor("s2", &s2);
|
||||||
|
|
||||||
@@ -111,6 +115,7 @@ TEST(PacketTransportSensorTest, PingKeyIncludedInTransmittedPacket) {
|
|||||||
responder.set_encryption_key(key);
|
responder.set_encryption_key(key);
|
||||||
sensor::Sensor local_sensor;
|
sensor::Sensor local_sensor;
|
||||||
local_sensor.state = 77.7f;
|
local_sensor.state = 77.7f;
|
||||||
|
responder.set_sensor_count(1);
|
||||||
responder.add_sensor("temp", &local_sensor);
|
responder.add_sensor("temp", &local_sensor);
|
||||||
|
|
||||||
// Requester sends a MAGIC_PING that the responder processes
|
// Requester sends a MAGIC_PING that the responder processes
|
||||||
@@ -148,6 +153,7 @@ TEST(PacketTransportSensorTest, MissingPingKeyBlocksSensorData) {
|
|||||||
responder.set_encryption_key(key);
|
responder.set_encryption_key(key);
|
||||||
sensor::Sensor local_sensor;
|
sensor::Sensor local_sensor;
|
||||||
local_sensor.state = 77.7f;
|
local_sensor.state = 77.7f;
|
||||||
|
responder.set_sensor_count(1);
|
||||||
responder.add_sensor("temp", &local_sensor);
|
responder.add_sensor("temp", &local_sensor);
|
||||||
responder.send_data_(true);
|
responder.send_data_(true);
|
||||||
ASSERT_EQ(responder.sent_packets.size(), 1u);
|
ASSERT_EQ(responder.sent_packets.size(), 1u);
|
||||||
|
|||||||
Reference in New Issue
Block a user