mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	wip
This commit is contained in:
		| @@ -9,70 +9,33 @@ import subprocess | |||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| # Component namespace patterns | # Pattern to extract ESPHome component namespaces dynamically | ||||||
| COMPONENT_PATTERNS = { | ESPHOME_COMPONENT_PATTERN = re.compile(r"esphome::([a-zA-Z0-9_]+)::") | ||||||
|     "api": re.compile(r"esphome::api::"), |  | ||||||
|     "wifi": re.compile(r"esphome::wifi::"), |  | ||||||
|     "mqtt": re.compile(r"esphome::mqtt::"), | # Get the list of actual ESPHome components by scanning the components directory | ||||||
|     "web_server": re.compile(r"esphome::web_server::"), | def get_esphome_components(): | ||||||
|     "sensor": re.compile(r"esphome::sensor::"), |     """Get set of actual ESPHome components from the components directory.""" | ||||||
|     "binary_sensor": re.compile(r"esphome::binary_sensor::"), |     components = set() | ||||||
|     "switch": re.compile(r"esphome::switch_::"), |  | ||||||
|     "light": re.compile(r"esphome::light::"), |     # Find the components directory relative to this file | ||||||
|     "cover": re.compile(r"esphome::cover::"), |     current_dir = Path(__file__).parent | ||||||
|     "climate": re.compile(r"esphome::climate::"), |     components_dir = current_dir / "components" | ||||||
|     "fan": re.compile(r"esphome::fan::"), |  | ||||||
|     "display": re.compile(r"esphome::display::"), |     if components_dir.exists() and components_dir.is_dir(): | ||||||
|     "logger": re.compile(r"esphome::logger::"), |         for item in components_dir.iterdir(): | ||||||
|     "ota": re.compile(r"esphome::ota::"), |             if ( | ||||||
|     "time": re.compile(r"esphome::time::"), |                 item.is_dir() | ||||||
|     "sun": re.compile(r"esphome::sun::"), |                 and not item.name.startswith(".") | ||||||
|     "text_sensor": re.compile(r"esphome::text_sensor::"), |                 and not item.name.startswith("__") | ||||||
|     "script": re.compile(r"esphome::script::"), |             ): | ||||||
|     "interval": re.compile(r"esphome::interval::"), |                 components.add(item.name) | ||||||
|     "json": re.compile(r"esphome::json::"), |  | ||||||
|     "network": re.compile(r"esphome::network::"), |     return components | ||||||
|     "mdns": re.compile(r"esphome::mdns::"), |  | ||||||
|     "i2c": re.compile(r"esphome::i2c::"), |  | ||||||
|     "spi": re.compile(r"esphome::spi::"), | # Cache the component list | ||||||
|     "uart": re.compile(r"esphome::uart::"), | ESPHOME_COMPONENTS = get_esphome_components() | ||||||
|     "dallas": re.compile(r"esphome::dallas::"), |  | ||||||
|     "dht": re.compile(r"esphome::dht::"), |  | ||||||
|     "adc": re.compile(r"esphome::adc::"), |  | ||||||
|     "pwm": re.compile(r"esphome::pwm::"), |  | ||||||
|     "ledc": re.compile(r"esphome::ledc::"), |  | ||||||
|     "gpio": re.compile(r"esphome::gpio::"), |  | ||||||
|     "esp32": re.compile(r"esphome::esp32::"), |  | ||||||
|     "esp8266": re.compile(r"esphome::esp8266::"), |  | ||||||
|     "remote": re.compile(r"esphome::remote_"), |  | ||||||
|     "rf_bridge": re.compile(r"esphome::rf_bridge::"), |  | ||||||
|     "captive_portal": re.compile(r"esphome::captive_portal::"), |  | ||||||
|     "deep_sleep": re.compile(r"esphome::deep_sleep::"), |  | ||||||
|     "bluetooth_proxy": re.compile(r"esphome::bluetooth_proxy::"), |  | ||||||
|     "esp32_ble": re.compile(r"esphome::esp32_ble::"), |  | ||||||
|     "esp32_ble_tracker": re.compile(r"esphome::esp32_ble_tracker::"), |  | ||||||
|     "ethernet": re.compile(r"esphome::ethernet::"), |  | ||||||
|     "valve": re.compile(r"esphome::valve::"), |  | ||||||
|     "lock": re.compile(r"esphome::lock::"), |  | ||||||
|     "alarm_control_panel": re.compile(r"esphome::alarm_control_panel::"), |  | ||||||
|     "number": re.compile(r"esphome::number::"), |  | ||||||
|     "select": re.compile(r"esphome::select::"), |  | ||||||
|     "button": re.compile(r"esphome::button::"), |  | ||||||
|     "datetime": re.compile(r"esphome::datetime::"), |  | ||||||
|     "text": re.compile(r"esphome::text::"), |  | ||||||
|     "media_player": re.compile(r"esphome::media_player::"), |  | ||||||
|     "microphone": re.compile(r"esphome::microphone::"), |  | ||||||
|     "speaker": re.compile(r"esphome::speaker::"), |  | ||||||
|     "voice_assistant": re.compile(r"esphome::voice_assistant::"), |  | ||||||
|     "update": re.compile(r"esphome::update::"), |  | ||||||
|     "image": re.compile(r"esphome::image::"), |  | ||||||
|     "font": re.compile(r"esphome::font::"), |  | ||||||
|     "color": re.compile(r"esphome::color::"), |  | ||||||
|     "graph": re.compile(r"esphome::graph::"), |  | ||||||
|     "qr_code": re.compile(r"esphome::qr_code::"), |  | ||||||
|     "touchscreen": re.compile(r"esphome::touchscreen::"), |  | ||||||
|     "lvgl": re.compile(r"esphome::lvgl::"), |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class MemorySection: | class MemorySection: | ||||||
| @@ -277,14 +240,22 @@ class MemoryAnalyzer: | |||||||
|         # Demangle C++ names if needed |         # Demangle C++ names if needed | ||||||
|         demangled = self._demangle_symbol(symbol_name) |         demangled = self._demangle_symbol(symbol_name) | ||||||
|  |  | ||||||
|         # Check against specific component patterns first (skip 'core') |         # Check for ESPHome component namespaces dynamically | ||||||
|         for component, pattern in COMPONENT_PATTERNS.items(): |         # Pattern: esphome::component_name:: (with trailing ::) | ||||||
|             if component == "core": |         match = ESPHOME_COMPONENT_PATTERN.search(demangled) | ||||||
|                 continue |         if match: | ||||||
|             if pattern.search(demangled): |             component_name = match.group(1) | ||||||
|                 return f"[esphome]{component}" |             # Strip trailing underscore if present (e.g., switch_ -> switch) | ||||||
|  |             component_name = component_name.rstrip("_") | ||||||
|  |  | ||||||
|         # Check for esphome core namespace last |             # Check if this is an actual component or core | ||||||
|  |             if component_name in ESPHOME_COMPONENTS: | ||||||
|  |                 return f"[esphome]{component_name}" | ||||||
|  |             else: | ||||||
|  |                 return "[esphome]core" | ||||||
|  |  | ||||||
|  |         # Check for esphome core namespace (no component namespace) | ||||||
|  |         # This catches esphome::ClassName or esphome::function_name | ||||||
|         if "esphome::" in demangled: |         if "esphome::" in demangled: | ||||||
|             return "[esphome]core" |             return "[esphome]core" | ||||||
|  |  | ||||||
| @@ -480,6 +451,11 @@ class MemoryAnalyzer: | |||||||
|             return "bluetooth" |             return "bluetooth" | ||||||
|         elif "coex" in symbol_name: |         elif "coex" in symbol_name: | ||||||
|             return "wifi_bt_coex" |             return "wifi_bt_coex" | ||||||
|  |         elif "r_" in symbol_name and any( | ||||||
|  |             bt in symbol_name for bt in ["ble", "lld", "llc", "llm"] | ||||||
|  |         ): | ||||||
|  |             # ROM bluetooth functions | ||||||
|  |             return "bluetooth_rom" | ||||||
|  |  | ||||||
|         # Power management |         # Power management | ||||||
|         if any( |         if any( | ||||||
| @@ -556,6 +532,171 @@ class MemoryAnalyzer: | |||||||
|         if "dhcp" in symbol_name or "handle_dhcp" in symbol_name: |         if "dhcp" in symbol_name or "handle_dhcp" in symbol_name: | ||||||
|             return "dhcp" |             return "dhcp" | ||||||
|  |  | ||||||
|  |         # JSON parsing | ||||||
|  |         if any( | ||||||
|  |             json in demangled | ||||||
|  |             for json in [ | ||||||
|  |                 "ArduinoJson", | ||||||
|  |                 "JsonDocument", | ||||||
|  |                 "JsonArray", | ||||||
|  |                 "JsonObject", | ||||||
|  |                 "deserialize", | ||||||
|  |                 "serialize", | ||||||
|  |             ] | ||||||
|  |         ): | ||||||
|  |             return "json_lib" | ||||||
|  |  | ||||||
|  |         # HTTP/Web related | ||||||
|  |         if any( | ||||||
|  |             http in demangled | ||||||
|  |             for http in ["HTTP", "http_", "Request", "Response", "Uri", "WebSocket"] | ||||||
|  |         ): | ||||||
|  |             return "http_lib" | ||||||
|  |  | ||||||
|  |         # Ethernet PHY drivers | ||||||
|  |         if any( | ||||||
|  |             eth in symbol_name | ||||||
|  |             for eth in [ | ||||||
|  |                 "emac_", | ||||||
|  |                 "eth_phy_", | ||||||
|  |                 "phy_tlk110", | ||||||
|  |                 "phy_lan87", | ||||||
|  |                 "phy_ip101", | ||||||
|  |                 "phy_rtl", | ||||||
|  |                 "phy_dp83", | ||||||
|  |                 "phy_ksz", | ||||||
|  |             ] | ||||||
|  |         ): | ||||||
|  |             return "ethernet_phy" | ||||||
|  |  | ||||||
|  |         # Task/Thread management | ||||||
|  |         if any(task in symbol_name for task in ["pthread_", "thread_", "_task_"]): | ||||||
|  |             return "threading" | ||||||
|  |  | ||||||
|  |         # Mutex/Semaphore | ||||||
|  |         if any( | ||||||
|  |             sync in symbol_name | ||||||
|  |             for sync in ["mutex", "semaphore", "spinlock", "portMUX"] | ||||||
|  |         ): | ||||||
|  |             return "synchronization" | ||||||
|  |  | ||||||
|  |         # String formatting | ||||||
|  |         if any( | ||||||
|  |             fmt in symbol_name | ||||||
|  |             for fmt in [ | ||||||
|  |                 "snprintf", | ||||||
|  |                 "vsnprintf", | ||||||
|  |                 "sprintf", | ||||||
|  |                 "vsprintf", | ||||||
|  |                 "sscanf", | ||||||
|  |                 "vsscanf", | ||||||
|  |             ] | ||||||
|  |         ): | ||||||
|  |             return "string_formatting" | ||||||
|  |  | ||||||
|  |         # Math functions | ||||||
|  |         if ( | ||||||
|  |             any( | ||||||
|  |                 math in symbol_name | ||||||
|  |                 for math in [ | ||||||
|  |                     "sin", | ||||||
|  |                     "cos", | ||||||
|  |                     "tan", | ||||||
|  |                     "sqrt", | ||||||
|  |                     "pow", | ||||||
|  |                     "exp", | ||||||
|  |                     "log", | ||||||
|  |                     "atan", | ||||||
|  |                     "asin", | ||||||
|  |                     "acos", | ||||||
|  |                     "floor", | ||||||
|  |                     "ceil", | ||||||
|  |                     "fabs", | ||||||
|  |                     "round", | ||||||
|  |                 ] | ||||||
|  |             ) | ||||||
|  |             and len(symbol_name) < 20 | ||||||
|  |         ): | ||||||
|  |             return "math_lib" | ||||||
|  |  | ||||||
|  |         # Random number generation | ||||||
|  |         if any(rng in symbol_name for rng in ["rand", "random", "rng_", "prng"]): | ||||||
|  |             return "random" | ||||||
|  |  | ||||||
|  |         # Time functions | ||||||
|  |         if any( | ||||||
|  |             time in symbol_name | ||||||
|  |             for time in [ | ||||||
|  |                 "time", | ||||||
|  |                 "clock", | ||||||
|  |                 "gettimeofday", | ||||||
|  |                 "settimeofday", | ||||||
|  |                 "localtime", | ||||||
|  |                 "gmtime", | ||||||
|  |                 "mktime", | ||||||
|  |                 "strftime", | ||||||
|  |             ] | ||||||
|  |         ): | ||||||
|  |             return "time_lib" | ||||||
|  |  | ||||||
|  |         # Console/UART output | ||||||
|  |         if any( | ||||||
|  |             console in symbol_name | ||||||
|  |             for console in [ | ||||||
|  |                 "console_", | ||||||
|  |                 "uart_tx", | ||||||
|  |                 "uart_rx", | ||||||
|  |                 "puts", | ||||||
|  |                 "putchar", | ||||||
|  |                 "getchar", | ||||||
|  |             ] | ||||||
|  |         ): | ||||||
|  |             return "console_io" | ||||||
|  |  | ||||||
|  |         # ROM functions | ||||||
|  |         if symbol_name.startswith("r_") or symbol_name.startswith("rom_"): | ||||||
|  |             return "rom_functions" | ||||||
|  |  | ||||||
|  |         # Compiler generated code | ||||||
|  |         if any( | ||||||
|  |             gen in symbol_name | ||||||
|  |             for gen in [ | ||||||
|  |                 "__divdi3", | ||||||
|  |                 "__udivdi3", | ||||||
|  |                 "__moddi3", | ||||||
|  |                 "__muldi3", | ||||||
|  |                 "__ashldi3", | ||||||
|  |                 "__ashrdi3", | ||||||
|  |                 "__lshrdi3", | ||||||
|  |                 "__cmpdi2", | ||||||
|  |                 "__fixdfdi", | ||||||
|  |                 "__floatdidf", | ||||||
|  |             ] | ||||||
|  |         ): | ||||||
|  |             return "compiler_runtime" | ||||||
|  |  | ||||||
|  |         # Exception handling | ||||||
|  |         if any( | ||||||
|  |             exc in symbol_name for exc in ["__cxa_", "_Unwind_", "__gcc_personality"] | ||||||
|  |         ): | ||||||
|  |             return "exception_handling" | ||||||
|  |  | ||||||
|  |         # RTTI (Run-Time Type Information) | ||||||
|  |         if "__type_info" in demangled or "__class_type_info" in demangled: | ||||||
|  |             return "rtti" | ||||||
|  |  | ||||||
|  |         # Static initializers | ||||||
|  |         if "_GLOBAL__sub_I_" in symbol_name or "__static_initialization" in demangled: | ||||||
|  |             return "static_init" | ||||||
|  |  | ||||||
|  |         # Weak symbols | ||||||
|  |         if "__weak_" in symbol_name: | ||||||
|  |             return "weak_symbols" | ||||||
|  |  | ||||||
|  |         # Compiler builtins | ||||||
|  |         if "__builtin_" in symbol_name: | ||||||
|  |             return "compiler_builtins" | ||||||
|  |  | ||||||
|         return "other" |         return "other" | ||||||
|  |  | ||||||
|     def _batch_demangle_symbols(self, symbols: list[str]) -> None: |     def _batch_demangle_symbols(self, symbols: list[str]) -> None: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user