#include "debug_component.h" #include #include "esphome/core/application.h" #include "esphome/core/hal.h" #include "esphome/core/helpers.h" #include "esphome/core/log.h" #include "esphome/core/version.h" #include #include namespace esphome { namespace debug { static const char *const TAG = "debug"; void DebugComponent::dump_config() { ESP_LOGCONFIG(TAG, "Debug component:"); #ifdef USE_TEXT_SENSOR LOG_TEXT_SENSOR(" ", "Device info", this->device_info_); #endif // USE_TEXT_SENSOR #ifdef USE_SENSOR LOG_SENSOR(" ", "Free space on heap", this->free_sensor_); LOG_SENSOR(" ", "Largest free heap block", this->block_sensor_); LOG_SENSOR(" ", "CPU frequency", this->cpu_frequency_sensor_); #if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2) LOG_SENSOR(" ", "Heap fragmentation", this->fragmentation_sensor_); #endif // defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2) #endif // USE_SENSOR char device_info_buffer[DEVICE_INFO_BUFFER_SIZE]; ESP_LOGD(TAG, "ESPHome version %s", ESPHOME_VERSION); size_t pos = buf_append_printf(device_info_buffer, DEVICE_INFO_BUFFER_SIZE, 0, "%s", ESPHOME_VERSION); this->free_heap_ = get_free_heap_(); ESP_LOGD(TAG, "Free Heap Size: %" PRIu32 " bytes", this->free_heap_); pos = get_device_info_(std::span(device_info_buffer), pos); #ifdef USE_TEXT_SENSOR if (this->device_info_ != nullptr) { this->device_info_->publish_state(device_info_buffer, pos); } if (this->reset_reason_ != nullptr) { char reset_reason_buffer[RESET_REASON_BUFFER_SIZE]; this->reset_reason_->publish_state( get_reset_reason_(std::span(reset_reason_buffer))); } #endif // USE_TEXT_SENSOR #if defined(USE_ESP32) || defined(USE_ZEPHYR) this->log_partition_info_(); // Log partition information #endif } void DebugComponent::loop() { // log when free heap space has halved uint32_t new_free_heap = get_free_heap_(); if (new_free_heap < this->free_heap_ / 2) { this->free_heap_ = new_free_heap; ESP_LOGD(TAG, "Free Heap Size: %" PRIu32 " bytes", this->free_heap_); this->status_momentary_warning("heap", 1000); } #ifdef USE_SENSOR // calculate loop time - from last call to this one if (this->loop_time_sensor_ != nullptr) { uint32_t now = App.get_loop_component_start_time(); uint32_t loop_time = now - this->last_loop_timetag_; this->max_loop_time_ = std::max(this->max_loop_time_, loop_time); this->last_loop_timetag_ = now; } #endif // USE_SENSOR } void DebugComponent::update() { #ifdef USE_SENSOR if (this->free_sensor_ != nullptr) { this->free_sensor_->publish_state(get_free_heap_()); } if (this->loop_time_sensor_ != nullptr) { this->loop_time_sensor_->publish_state(this->max_loop_time_); this->max_loop_time_ = 0; } if (this->cpu_frequency_sensor_ != nullptr) { this->cpu_frequency_sensor_->publish_state(arch_get_cpu_freq_hz()); } #endif // USE_SENSOR update_platform_(); } float DebugComponent::get_setup_priority() const { return setup_priority::LATE; } } // namespace debug } // namespace esphome