Merge remote-tracking branch 'upstream/dev' into web_server_stack_format

This commit is contained in:
J. Nick Koston
2025-12-21 22:01:29 -10:00
125 changed files with 3063 additions and 767 deletions
@@ -135,6 +135,13 @@ bool ListEntitiesIterator::on_alarm_control_panel(alarm_control_panel::AlarmCont
}
#endif
#ifdef USE_WATER_HEATER
bool ListEntitiesIterator::on_water_heater(water_heater::WaterHeater *obj) {
// Water heater web_server support not yet implemented - this stub acknowledges the entity
return true;
}
#endif
#ifdef USE_EVENT
bool ListEntitiesIterator::on_event(event::Event *obj) {
// Null event type, since we are just iterating over entities
@@ -79,6 +79,9 @@ class ListEntitiesIterator : public ComponentIterator {
#ifdef USE_ALARM_CONTROL_PANEL
bool on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *obj) override;
#endif
#ifdef USE_WATER_HEATER
bool on_water_heater(water_heater::WaterHeater *obj) override;
#endif
#ifdef USE_EVENT
bool on_event(event::Event *obj) override;
#endif
@@ -84,9 +84,9 @@ void OTARequestHandler::report_ota_progress_(AsyncWebServerRequest *request) {
} else {
ESP_LOGD(TAG, "OTA in progress: %" PRIu32 " bytes read", this->ota_read_length_);
}
#ifdef USE_OTA_STATE_CALLBACK
// Report progress - use call_deferred since we're in web server task
this->parent_->state_callback_.call_deferred(ota::OTA_IN_PROGRESS, percentage, 0);
#ifdef USE_OTA_STATE_LISTENER
// Report progress - use notify_state_deferred_ since we're in web server task
this->parent_->notify_state_deferred_(ota::OTA_IN_PROGRESS, percentage, 0);
#endif
this->last_ota_progress_ = now;
}
@@ -114,9 +114,9 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf
// Initialize OTA on first call
this->ota_init_(filename.c_str());
#ifdef USE_OTA_STATE_CALLBACK
// Notify OTA started - use call_deferred since we're in web server task
this->parent_->state_callback_.call_deferred(ota::OTA_STARTED, 0.0f, 0);
#ifdef USE_OTA_STATE_LISTENER
// Notify OTA started - use notify_state_deferred_ since we're in web server task
this->parent_->notify_state_deferred_(ota::OTA_STARTED, 0.0f, 0);
#endif
// Platform-specific pre-initialization
@@ -134,9 +134,9 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf
this->ota_backend_ = ota::make_ota_backend();
if (!this->ota_backend_) {
ESP_LOGE(TAG, "Failed to create OTA backend");
#ifdef USE_OTA_STATE_CALLBACK
this->parent_->state_callback_.call_deferred(ota::OTA_ERROR, 0.0f,
static_cast<uint8_t>(ota::OTA_RESPONSE_ERROR_UNKNOWN));
#ifdef USE_OTA_STATE_LISTENER
this->parent_->notify_state_deferred_(ota::OTA_ERROR, 0.0f,
static_cast<uint8_t>(ota::OTA_RESPONSE_ERROR_UNKNOWN));
#endif
return;
}
@@ -148,8 +148,8 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf
if (error_code != ota::OTA_RESPONSE_OK) {
ESP_LOGE(TAG, "OTA begin failed: %d", error_code);
this->ota_backend_.reset();
#ifdef USE_OTA_STATE_CALLBACK
this->parent_->state_callback_.call_deferred(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#ifdef USE_OTA_STATE_LISTENER
this->parent_->notify_state_deferred_(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#endif
return;
}
@@ -166,8 +166,8 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf
ESP_LOGE(TAG, "OTA write failed: %d", error_code);
this->ota_backend_->abort();
this->ota_backend_.reset();
#ifdef USE_OTA_STATE_CALLBACK
this->parent_->state_callback_.call_deferred(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#ifdef USE_OTA_STATE_LISTENER
this->parent_->notify_state_deferred_(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#endif
return;
}
@@ -186,15 +186,15 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf
error_code = this->ota_backend_->end();
if (error_code == ota::OTA_RESPONSE_OK) {
this->ota_success_ = true;
#ifdef USE_OTA_STATE_CALLBACK
// Report completion before reboot - use call_deferred since we're in web server task
this->parent_->state_callback_.call_deferred(ota::OTA_COMPLETED, 100.0f, 0);
#ifdef USE_OTA_STATE_LISTENER
// Report completion before reboot - use notify_state_deferred_ since we're in web server task
this->parent_->notify_state_deferred_(ota::OTA_COMPLETED, 100.0f, 0);
#endif
this->schedule_ota_reboot_();
} else {
ESP_LOGE(TAG, "OTA end failed: %d", error_code);
#ifdef USE_OTA_STATE_CALLBACK
this->parent_->state_callback_.call_deferred(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#ifdef USE_OTA_STATE_LISTENER
this->parent_->notify_state_deferred_(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#endif
}
this->ota_backend_.reset();
@@ -232,10 +232,6 @@ void WebServerOTAComponent::setup() {
// AsyncWebServer takes ownership of the handler and will delete it when the server is destroyed
base->add_handler(new OTARequestHandler(this)); // NOLINT
#ifdef USE_OTA_STATE_CALLBACK
// Register with global OTA callback system
ota::register_ota_platform(this);
#endif
}
void WebServerOTAComponent::dump_config() { ESP_LOGCONFIG(TAG, "Web Server OTA"); }
+26 -7
View File
@@ -1052,8 +1052,14 @@ std::string WebServer::date_json(datetime::DateEntity *obj, JsonDetail start_con
json::JsonBuilder builder;
JsonObject root = builder.root();
std::string value = str_sprintf("%d-%02d-%02d", obj->year, obj->month, obj->day);
set_json_icon_state_value(root, obj, "date", value.c_str(), value.c_str(), start_config);
// Format: YYYY-MM-DD (max 10 chars + null)
char value[12];
#ifdef USE_ESP8266
snprintf_P(value, sizeof(value), PSTR("%d-%02d-%02d"), obj->year, obj->month, obj->day);
#else
snprintf(value, sizeof(value), "%d-%02d-%02d", obj->year, obj->month, obj->day);
#endif
set_json_icon_state_value(root, obj, "date", value, value, start_config);
if (start_config == DETAIL_ALL) {
this->add_sorting_info_(root, obj);
}
@@ -1108,8 +1114,14 @@ std::string WebServer::time_json(datetime::TimeEntity *obj, JsonDetail start_con
json::JsonBuilder builder;
JsonObject root = builder.root();
std::string value = str_sprintf("%02d:%02d:%02d", obj->hour, obj->minute, obj->second);
set_json_icon_state_value(root, obj, "time", value.c_str(), value.c_str(), start_config);
// Format: HH:MM:SS (8 chars + null)
char value[12];
#ifdef USE_ESP8266
snprintf_P(value, sizeof(value), PSTR("%02d:%02d:%02d"), obj->hour, obj->minute, obj->second);
#else
snprintf(value, sizeof(value), "%02d:%02d:%02d", obj->hour, obj->minute, obj->second);
#endif
set_json_icon_state_value(root, obj, "time", value, value, start_config);
if (start_config == DETAIL_ALL) {
this->add_sorting_info_(root, obj);
}
@@ -1164,9 +1176,16 @@ std::string WebServer::datetime_json(datetime::DateTimeEntity *obj, JsonDetail s
json::JsonBuilder builder;
JsonObject root = builder.root();
std::string value =
str_sprintf("%d-%02d-%02d %02d:%02d:%02d", obj->year, obj->month, obj->day, obj->hour, obj->minute, obj->second);
set_json_icon_state_value(root, obj, "datetime", value.c_str(), value.c_str(), start_config);
// Format: YYYY-MM-DD HH:MM:SS (max 19 chars + null)
char value[24];
#ifdef USE_ESP8266
snprintf_P(value, sizeof(value), PSTR("%d-%02d-%02d %02d:%02d:%02d"), obj->year, obj->month, obj->day, obj->hour,
obj->minute, obj->second);
#else
snprintf(value, sizeof(value), "%d-%02d-%02d %02d:%02d:%02d", obj->year, obj->month, obj->day, obj->hour, obj->minute,
obj->second);
#endif
set_json_icon_state_value(root, obj, "datetime", value, value, start_config);
if (start_config == DETAIL_ALL) {
this->add_sorting_info_(root, obj);
}