1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-19 08:15:49 +00:00

Merge branch 'integration' into memory_api

This commit is contained in:
J. Nick Koston
2025-10-31 22:22:46 -05:00
3 changed files with 55 additions and 39 deletions

View File

@@ -671,18 +671,33 @@ async def write_image(config, all_frames=False):
resize = config.get(CONF_RESIZE) resize = config.get(CONF_RESIZE)
if is_svg_file(path): if is_svg_file(path):
# Local import so use of non-SVG files needn't require cairosvg installed # Local import so use of non-SVG files needn't require cairosvg installed
from pyexpat import ExpatError
from xml.etree.ElementTree import ParseError
from cairosvg import svg2png from cairosvg import svg2png
from cairosvg.helpers import PointError
if not resize: if not resize:
resize = (None, None) resize = (None, None)
with open(path, "rb") as file: try:
image = svg2png( with open(path, "rb") as file:
file_obj=file, image = svg2png(
output_width=resize[0], file_obj=file,
output_height=resize[1], output_width=resize[0],
) output_height=resize[1],
image = Image.open(io.BytesIO(image)) )
width, height = image.size image = Image.open(io.BytesIO(image))
width, height = image.size
except (
ValueError,
ParseError,
IndexError,
ExpatError,
AttributeError,
TypeError,
PointError,
) as e:
raise core.EsphomeError(f"Could not load SVG image {path}: {e}") from e
else: else:
image = Image.open(path) image = Image.open(path)
width, height = image.size width, height = image.size

View File

@@ -220,50 +220,51 @@ void DeferredUpdateEventSourceList::add_new_client(WebServer *ws, AsyncWebServer
DeferredUpdateEventSource *es = new DeferredUpdateEventSource(ws, "/events"); DeferredUpdateEventSource *es = new DeferredUpdateEventSource(ws, "/events");
this->push_back(es); this->push_back(es);
es->onConnect([this, ws, es](AsyncEventSourceClient *client) { es->onConnect([this, es](AsyncEventSourceClient *client) { this->on_client_connect_(es); });
ws->defer([this, ws, es]() { this->on_client_connect_(ws, es); });
});
es->onDisconnect([this, ws, es](AsyncEventSourceClient *client) { es->onDisconnect([this, es](AsyncEventSourceClient *client) { this->on_client_disconnect_(es); });
ws->defer([this, es]() { this->on_client_disconnect_((DeferredUpdateEventSource *) es); });
});
es->handleRequest(request); es->handleRequest(request);
} }
void DeferredUpdateEventSourceList::on_client_connect_(WebServer *ws, DeferredUpdateEventSource *source) { void DeferredUpdateEventSourceList::on_client_connect_(DeferredUpdateEventSource *source) {
// Configure reconnect timeout and send config WebServer *ws = source->web_server_;
// this should always go through since the AsyncEventSourceClient event queue is empty on connect ws->defer([this, ws, source]() {
std::string message = ws->get_config_json(); // Configure reconnect timeout and send config
source->try_send_nodefer(message.c_str(), "ping", millis(), 30000); // this should always go through since the AsyncEventSourceClient event queue is empty on connect
std::string message = ws->get_config_json();
source->try_send_nodefer(message.c_str(), "ping", millis(), 30000);
#ifdef USE_WEBSERVER_SORTING #ifdef USE_WEBSERVER_SORTING
for (auto &group : ws->sorting_groups_) { for (auto &group : ws->sorting_groups_) {
json::JsonBuilder builder; json::JsonBuilder builder;
JsonObject root = builder.root(); JsonObject root = builder.root();
root["name"] = group.second.name; root["name"] = group.second.name;
root["sorting_weight"] = group.second.weight; root["sorting_weight"] = group.second.weight;
message = builder.serialize(); message = builder.serialize();
// up to 31 groups should be able to be queued initially without defer // up to 31 groups should be able to be queued initially without defer
source->try_send_nodefer(message.c_str(), "sorting_group"); source->try_send_nodefer(message.c_str(), "sorting_group");
} }
#endif #endif
source->entities_iterator_.begin(ws->include_internal_); source->entities_iterator_.begin(ws->include_internal_);
// just dump them all up-front and take advantage of the deferred queue // just dump them all up-front and take advantage of the deferred queue
// on second thought that takes too long, but leaving the commented code here for debug purposes // on second thought that takes too long, but leaving the commented code here for debug purposes
// while(!source->entities_iterator_.completed()) { // while(!source->entities_iterator_.completed()) {
// source->entities_iterator_.advance(); // source->entities_iterator_.advance();
//} //}
});
} }
void DeferredUpdateEventSourceList::on_client_disconnect_(DeferredUpdateEventSource *source) { void DeferredUpdateEventSourceList::on_client_disconnect_(DeferredUpdateEventSource *source) {
// This method was called via WebServer->defer() and is no longer executing in the source->web_server_->defer([this, source]() {
// context of the network callback. The object is now dead and can be safely deleted. // This method was called via WebServer->defer() and is no longer executing in the
this->remove(source); // context of the network callback. The object is now dead and can be safely deleted.
delete source; // NOLINT this->remove(source);
delete source; // NOLINT
});
} }
#endif #endif

View File

@@ -141,7 +141,7 @@ class DeferredUpdateEventSource : public AsyncEventSource {
class DeferredUpdateEventSourceList : public std::list<DeferredUpdateEventSource *> { class DeferredUpdateEventSourceList : public std::list<DeferredUpdateEventSource *> {
protected: protected:
void on_client_connect_(WebServer *ws, DeferredUpdateEventSource *source); void on_client_connect_(DeferredUpdateEventSource *source);
void on_client_disconnect_(DeferredUpdateEventSource *source); void on_client_disconnect_(DeferredUpdateEventSource *source);
public: public: