mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Refactor StorageJSON to keep loaded_integrations a set until its converted to JSON (#5793)
* Refactor StorageJSON to keep loaded_integrations a set until its converted to a dict after #5792 we will be checking loaded_integrations often. ESPHome core keep uses a set, but it would get converted to a list when passed through StorageJSON. Keep it a set until its needed to be read/write to JSON so we do not have to linear searches on it since they have a time complexity of O(n) vs O(1) * legacy
This commit is contained in:
		| @@ -285,7 +285,7 @@ class DashboardEntry: | ||||
|                 "name": self.name, | ||||
|                 "friendly_name": self.friendly_name, | ||||
|                 "configuration": self.filename, | ||||
|                 "loaded_integrations": self.loaded_integrations, | ||||
|                 "loaded_integrations": sorted(self.loaded_integrations), | ||||
|                 "deployed_version": self.update_old, | ||||
|                 "current_version": self.update_new, | ||||
|                 "path": self.path, | ||||
| @@ -381,7 +381,7 @@ class DashboardEntry: | ||||
|         return const.__version__ | ||||
|  | ||||
|     @property | ||||
|     def loaded_integrations(self) -> list[str]: | ||||
|     def loaded_integrations(self) -> set[str]: | ||||
|         if self.storage is None: | ||||
|             return [] | ||||
|         return self.storage.loaded_integrations | ||||
|   | ||||
| @@ -1,21 +1,15 @@ | ||||
| from __future__ import annotations | ||||
| import binascii | ||||
| import codecs | ||||
| from datetime import datetime | ||||
| import json | ||||
| import logging | ||||
| import os | ||||
| from typing import Optional | ||||
| from datetime import datetime | ||||
|  | ||||
| from esphome import const | ||||
| from esphome.const import CONF_DISABLED, CONF_MDNS | ||||
| from esphome.core import CORE | ||||
| from esphome.helpers import write_file_if_changed | ||||
|  | ||||
|  | ||||
| from esphome.const import ( | ||||
|     CONF_MDNS, | ||||
|     CONF_DISABLED, | ||||
| ) | ||||
|  | ||||
| from esphome.types import CoreType | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
| @@ -40,48 +34,47 @@ def trash_storage_path() -> str: | ||||
| class StorageJSON: | ||||
|     def __init__( | ||||
|         self, | ||||
|         storage_version, | ||||
|         name, | ||||
|         friendly_name, | ||||
|         comment, | ||||
|         esphome_version, | ||||
|         src_version, | ||||
|         address, | ||||
|         web_port, | ||||
|         target_platform, | ||||
|         build_path, | ||||
|         firmware_bin_path, | ||||
|         loaded_integrations, | ||||
|         no_mdns, | ||||
|     ): | ||||
|         storage_version: int, | ||||
|         name: str, | ||||
|         friendly_name: str, | ||||
|         comment: str, | ||||
|         esphome_version: str, | ||||
|         src_version: int | None, | ||||
|         address: str, | ||||
|         web_port: int | None, | ||||
|         target_platform: str, | ||||
|         build_path: str, | ||||
|         firmware_bin_path: str, | ||||
|         loaded_integrations: set[str], | ||||
|         no_mdns: bool, | ||||
|     ) -> None: | ||||
|         # Version of the storage JSON schema | ||||
|         assert storage_version is None or isinstance(storage_version, int) | ||||
|         self.storage_version: int = storage_version | ||||
|         self.storage_version = storage_version | ||||
|         # The name of the node | ||||
|         self.name: str = name | ||||
|         self.name = name | ||||
|         # The friendly name of the node | ||||
|         self.friendly_name: str = friendly_name | ||||
|         self.friendly_name = friendly_name | ||||
|         # The comment of the node | ||||
|         self.comment: str = comment | ||||
|         self.comment = comment | ||||
|         # The esphome version this was compiled with | ||||
|         self.esphome_version: str = esphome_version | ||||
|         self.esphome_version = esphome_version | ||||
|         # The version of the file in src/main.cpp - Used to migrate the file | ||||
|         assert src_version is None or isinstance(src_version, int) | ||||
|         self.src_version: int = src_version | ||||
|         self.src_version = src_version | ||||
|         # Address of the ESP, for example livingroom.local or a static IP | ||||
|         self.address: str = address | ||||
|         self.address = address | ||||
|         # Web server port of the ESP, for example 80 | ||||
|         assert web_port is None or isinstance(web_port, int) | ||||
|         self.web_port: int = web_port | ||||
|         self.web_port = web_port | ||||
|         # The type of hardware in use, like "ESP32", "ESP32C3", "ESP8266", etc. | ||||
|         self.target_platform: str = target_platform | ||||
|         self.target_platform = target_platform | ||||
|         # The absolute path to the platformio project | ||||
|         self.build_path: str = build_path | ||||
|         self.build_path = build_path | ||||
|         # The absolute path to the firmware binary | ||||
|         self.firmware_bin_path: str = firmware_bin_path | ||||
|         # A list of strings of names of loaded integrations | ||||
|         self.loaded_integrations: list[str] = loaded_integrations | ||||
|         self.loaded_integrations.sort() | ||||
|         self.firmware_bin_path = firmware_bin_path | ||||
|         # A set of strings of names of loaded integrations | ||||
|         self.loaded_integrations = loaded_integrations | ||||
|         # Is mDNS disabled | ||||
|         self.no_mdns = no_mdns | ||||
|  | ||||
| @@ -98,7 +91,7 @@ class StorageJSON: | ||||
|             "esp_platform": self.target_platform, | ||||
|             "build_path": self.build_path, | ||||
|             "firmware_bin_path": self.firmware_bin_path, | ||||
|             "loaded_integrations": self.loaded_integrations, | ||||
|             "loaded_integrations": sorted(self.loaded_integrations), | ||||
|             "no_mdns": self.no_mdns, | ||||
|         } | ||||
|  | ||||
| @@ -109,9 +102,7 @@ class StorageJSON: | ||||
|         write_file_if_changed(path, self.to_json()) | ||||
|  | ||||
|     @staticmethod | ||||
|     def from_esphome_core( | ||||
|         esph: CoreType, old: Optional["StorageJSON"] | ||||
|     ) -> "StorageJSON": | ||||
|     def from_esphome_core(esph: CoreType, old: StorageJSON | None) -> StorageJSON: | ||||
|         hardware = esph.target_platform.upper() | ||||
|         if esph.is_esp32: | ||||
|             from esphome.components import esp32 | ||||
| @@ -129,7 +120,7 @@ class StorageJSON: | ||||
|             target_platform=hardware, | ||||
|             build_path=esph.build_path, | ||||
|             firmware_bin_path=esph.firmware_bin, | ||||
|             loaded_integrations=list(esph.loaded_integrations), | ||||
|             loaded_integrations=esph.loaded_integrations, | ||||
|             no_mdns=( | ||||
|                 CONF_MDNS in esph.config | ||||
|                 and CONF_DISABLED in esph.config[CONF_MDNS] | ||||
| @@ -140,7 +131,7 @@ class StorageJSON: | ||||
|     @staticmethod | ||||
|     def from_wizard( | ||||
|         name: str, friendly_name: str, address: str, platform: str | ||||
|     ) -> "StorageJSON": | ||||
|     ) -> StorageJSON: | ||||
|         return StorageJSON( | ||||
|             storage_version=1, | ||||
|             name=name, | ||||
| @@ -153,12 +144,12 @@ class StorageJSON: | ||||
|             target_platform=platform, | ||||
|             build_path=None, | ||||
|             firmware_bin_path=None, | ||||
|             loaded_integrations=[], | ||||
|             loaded_integrations=set(), | ||||
|             no_mdns=False, | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def _load_impl(path: str) -> Optional["StorageJSON"]: | ||||
|     def _load_impl(path: str) -> StorageJSON | None: | ||||
|         with codecs.open(path, "r", encoding="utf-8") as f_handle: | ||||
|             storage = json.load(f_handle) | ||||
|         storage_version = storage["storage_version"] | ||||
| @@ -174,7 +165,7 @@ class StorageJSON: | ||||
|         esp_platform = storage.get("esp_platform") | ||||
|         build_path = storage.get("build_path") | ||||
|         firmware_bin_path = storage.get("firmware_bin_path") | ||||
|         loaded_integrations = storage.get("loaded_integrations", []) | ||||
|         loaded_integrations = set(storage.get("loaded_integrations", [])) | ||||
|         no_mdns = storage.get("no_mdns", False) | ||||
|         return StorageJSON( | ||||
|             storage_version, | ||||
| @@ -193,7 +184,7 @@ class StorageJSON: | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def load(path: str) -> Optional["StorageJSON"]: | ||||
|     def load(path: str) -> StorageJSON | None: | ||||
|         try: | ||||
|             return StorageJSON._load_impl(path) | ||||
|         except Exception:  # pylint: disable=broad-except | ||||
| @@ -215,7 +206,7 @@ class EsphomeStorageJSON: | ||||
|         # The last time ESPHome checked for an update as an isoformat encoded str | ||||
|         self.last_update_check_str: str = last_update_check | ||||
|         # Cache of the version gotten in the last version check | ||||
|         self.remote_version: Optional[str] = remote_version | ||||
|         self.remote_version: str | None = remote_version | ||||
|  | ||||
|     def as_dict(self) -> dict: | ||||
|         return { | ||||
| @@ -226,7 +217,7 @@ class EsphomeStorageJSON: | ||||
|         } | ||||
|  | ||||
|     @property | ||||
|     def last_update_check(self) -> Optional[datetime]: | ||||
|     def last_update_check(self) -> datetime | None: | ||||
|         try: | ||||
|             return datetime.strptime(self.last_update_check_str, "%Y-%m-%dT%H:%M:%S") | ||||
|         except Exception:  # pylint: disable=broad-except | ||||
| @@ -243,7 +234,7 @@ class EsphomeStorageJSON: | ||||
|         write_file_if_changed(path, self.to_json()) | ||||
|  | ||||
|     @staticmethod | ||||
|     def _load_impl(path: str) -> Optional["EsphomeStorageJSON"]: | ||||
|     def _load_impl(path: str) -> EsphomeStorageJSON | None: | ||||
|         with codecs.open(path, "r", encoding="utf-8") as f_handle: | ||||
|             storage = json.load(f_handle) | ||||
|         storage_version = storage["storage_version"] | ||||
| @@ -255,14 +246,14 @@ class EsphomeStorageJSON: | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def load(path: str) -> Optional["EsphomeStorageJSON"]: | ||||
|     def load(path: str) -> EsphomeStorageJSON | None: | ||||
|         try: | ||||
|             return EsphomeStorageJSON._load_impl(path) | ||||
|         except Exception:  # pylint: disable=broad-except | ||||
|             return None | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_default() -> "EsphomeStorageJSON": | ||||
|     def get_default() -> EsphomeStorageJSON: | ||||
|         return EsphomeStorageJSON( | ||||
|             storage_version=1, | ||||
|             cookie_secret=binascii.hexlify(os.urandom(64)).decode(), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user