mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	| @@ -12,7 +12,7 @@ import argcomplete | ||||
|  | ||||
| from esphome import const, writer, yaml_util | ||||
| import esphome.codegen as cg | ||||
| from esphome.config import iter_components, read_config, strip_default_ids | ||||
| from esphome.config import iter_component_configs, read_config, strip_default_ids | ||||
| from esphome.const import ( | ||||
|     ALLOWED_NAME_CHARS, | ||||
|     CONF_BAUD_RATE, | ||||
| @@ -196,7 +196,7 @@ def write_cpp(config): | ||||
| def generate_cpp_contents(config): | ||||
|     _LOGGER.info("Generating C++ source...") | ||||
|  | ||||
|     for name, component, conf in iter_components(CORE.config): | ||||
|     for name, component, conf in iter_component_configs(CORE.config): | ||||
|         if component.to_code is not None: | ||||
|             coro = wrap_to_code(name, component) | ||||
|             CORE.add_job(coro, conf) | ||||
|   | ||||
| @@ -36,6 +36,7 @@ _LOGGER = logging.getLogger(__name__) | ||||
| DOMAIN = "image" | ||||
| DEPENDENCIES = ["display"] | ||||
| MULTI_CONF = True | ||||
| MULTI_CONF_NO_DEFAULT = True | ||||
|  | ||||
| image_ns = cg.esphome_ns.namespace("image") | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,17 @@ _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| def iter_components(config): | ||||
|     for domain, conf in config.items(): | ||||
|         component = get_component(domain) | ||||
|         yield domain, component | ||||
|         if component.is_platform_component: | ||||
|             for p_config in conf: | ||||
|                 p_name = f"{domain}.{p_config[CONF_PLATFORM]}" | ||||
|                 platform = get_platform(domain, p_config[CONF_PLATFORM]) | ||||
|                 yield p_name, platform | ||||
|  | ||||
|  | ||||
| def iter_component_configs(config): | ||||
|     for domain, conf in config.items(): | ||||
|         component = get_component(domain) | ||||
|         if component.multi_conf: | ||||
| @@ -303,8 +314,10 @@ class LoadValidationStep(ConfigValidationStep): | ||||
|             # Ignore top-level keys starting with a dot | ||||
|             return | ||||
|         result.add_output_path([self.domain], self.domain) | ||||
|         result[self.domain] = self.conf | ||||
|         component = get_component(self.domain) | ||||
|         if component.multi_conf_no_default and isinstance(self.conf, core.AutoLoad): | ||||
|             self.conf = [] | ||||
|         result[self.domain] = self.conf | ||||
|         path = [self.domain] | ||||
|         if component is None: | ||||
|             result.add_str_error(f"Component not found: {self.domain}", path) | ||||
| @@ -424,7 +437,10 @@ class MetadataValidationStep(ConfigValidationStep): | ||||
|  | ||||
|     def run(self, result: Config) -> None: | ||||
|         if self.conf is None: | ||||
|             result[self.domain] = self.conf = {} | ||||
|             if self.comp.multi_conf and self.comp.multi_conf_no_default: | ||||
|                 result[self.domain] = self.conf = [] | ||||
|             else: | ||||
|                 result[self.domain] = self.conf = {} | ||||
|  | ||||
|         success = True | ||||
|         for dependency in self.comp.dependencies: | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| """Constants used by esphome.""" | ||||
|  | ||||
| __version__ = "2023.12.0b5" | ||||
| __version__ = "2023.12.0b6" | ||||
|  | ||||
| ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" | ||||
| VALID_SUBSTITUTIONS_CHARACTERS = ( | ||||
|   | ||||
| @@ -57,6 +57,10 @@ class ComponentManifest: | ||||
|     def multi_conf(self) -> bool: | ||||
|         return getattr(self.module, "MULTI_CONF", False) | ||||
|  | ||||
|     @property | ||||
|     def multi_conf_no_default(self) -> bool: | ||||
|         return getattr(self.module, "MULTI_CONF_NO_DEFAULT", False) | ||||
|  | ||||
|     @property | ||||
|     def to_code(self) -> Optional[Callable[[Any], None]]: | ||||
|         return getattr(self.module, "to_code", None) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import operator | ||||
| from functools import reduce | ||||
| import esphome.config_validation as cv | ||||
| from esphome.core import CORE, ID | ||||
| from esphome.core import CORE | ||||
|  | ||||
| from esphome.const import ( | ||||
|     CONF_INPUT, | ||||
| @@ -25,15 +25,16 @@ class PinRegistry(dict): | ||||
|     def reset(self): | ||||
|         self.pins_used = {} | ||||
|  | ||||
|     def get_count(self, key, number): | ||||
|     def get_count(self, key, id, number): | ||||
|         """ | ||||
|         Get the number of places a given pin is used. | ||||
|         :param key: The ID of the defining component | ||||
|         :param key: The key of the registered pin schema. | ||||
|         :param id: The ID of the defining component | ||||
|         :param number: The pin number | ||||
|         :return: The number of places the pin is used. | ||||
|         """ | ||||
|         pin_key = (key, number) | ||||
|         return self.pins_used[pin_key] if pin_key in self.pins_used else 0 | ||||
|         pin_key = (key, id, number) | ||||
|         return len(self.pins_used[pin_key]) if pin_key in self.pins_used else 0 | ||||
|  | ||||
|     def register(self, name, schema, final_validate=None): | ||||
|         """ | ||||
| @@ -65,9 +66,10 @@ class PinRegistry(dict): | ||||
|         result = self[key][1](conf) | ||||
|         if CONF_NUMBER in result: | ||||
|             # key maps to the pin schema | ||||
|             if isinstance(key, ID): | ||||
|                 key = key.id | ||||
|             pin_key = (key, result[CONF_NUMBER]) | ||||
|             if key != CORE.target_platform: | ||||
|                 pin_key = (key, conf[key], result[CONF_NUMBER]) | ||||
|             else: | ||||
|                 pin_key = (key, key, result[CONF_NUMBER]) | ||||
|             if pin_key not in self.pins_used: | ||||
|                 self.pins_used[pin_key] = [] | ||||
|             # client_id identifies the instance of the providing component | ||||
| @@ -101,7 +103,7 @@ class PinRegistry(dict): | ||||
|         Run the final validation for all pins, and check for reuse | ||||
|         :param fconf: The full config | ||||
|         """ | ||||
|         for (key, _), pin_list in self.pins_used.items(): | ||||
|         for (key, _, _), pin_list in self.pins_used.items(): | ||||
|             count = len(pin_list)  # number of places same pin used. | ||||
|             final_val_fun = self[key][2]  # final validation function | ||||
|             for pin_path, client_id, pin_config in pin_list: | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import re | ||||
| from pathlib import Path | ||||
| from typing import Union | ||||
|  | ||||
| from esphome.config import iter_components | ||||
| from esphome.config import iter_components, iter_component_configs | ||||
| from esphome.const import ( | ||||
|     HEADER_FILE_EXTENSIONS, | ||||
|     SOURCE_FILE_EXTENSIONS, | ||||
| @@ -70,14 +70,14 @@ UPLOAD_SPEED_OVERRIDE = { | ||||
|  | ||||
| def get_flags(key): | ||||
|     flags = set() | ||||
|     for _, component, conf in iter_components(CORE.config): | ||||
|     for _, component, conf in iter_component_configs(CORE.config): | ||||
|         flags |= getattr(component, key)(conf) | ||||
|     return flags | ||||
|  | ||||
|  | ||||
| def get_include_text(): | ||||
|     include_text = '#include "esphome.h"\nusing namespace esphome;\n' | ||||
|     for _, component, conf in iter_components(CORE.config): | ||||
|     for _, component, conf in iter_component_configs(CORE.config): | ||||
|         if not hasattr(component, "includes"): | ||||
|             continue | ||||
|         includes = component.includes | ||||
| @@ -232,7 +232,7 @@ the custom_components folder or the external_components feature. | ||||
|  | ||||
| def copy_src_tree(): | ||||
|     source_files: list[loader.FileResource] = [] | ||||
|     for _, component, _ in iter_components(CORE.config): | ||||
|     for _, component in iter_components(CORE.config): | ||||
|         source_files += component.resources | ||||
|     source_files_map = { | ||||
|         Path(x.package.replace(".", "/") + "/" + x.resource): x for x in source_files | ||||
|   | ||||
| @@ -1667,7 +1667,6 @@ binary_sensor: | ||||
|       mcp23xxx: mcp23s08_hub | ||||
|       # Use pin number 1 | ||||
|       number: 1 | ||||
|       allow_other_uses: true | ||||
|       # One of INPUT or INPUT_PULLUP | ||||
|       mode: INPUT_PULLUP | ||||
|       inverted: false | ||||
| @@ -2149,7 +2148,6 @@ output: | ||||
|     pin: | ||||
|       mcp23xxx: mcp23017_hub | ||||
|       number: 0 | ||||
|       allow_other_uses: true | ||||
|       mode: OUTPUT | ||||
|       inverted: false | ||||
|   - platform: gpio | ||||
| @@ -2157,7 +2155,6 @@ output: | ||||
|     pin: | ||||
|       mcp23xxx: mcp23008_hub | ||||
|       number: 0 | ||||
|       allow_other_uses: true | ||||
|       mode: OUTPUT | ||||
|       inverted: false | ||||
|   - platform: gpio | ||||
| @@ -2597,7 +2594,6 @@ switch: | ||||
|       mcp23xxx: mcp23s08_hub | ||||
|       # Use pin number 0 | ||||
|       number: 0 | ||||
|       allow_other_uses: true | ||||
|       mode: OUTPUT | ||||
|       inverted: false | ||||
|   - platform: gpio | ||||
|   | ||||
| @@ -401,7 +401,6 @@ switch: | ||||
|     pin: | ||||
|       mcp23xxx: mcp23017_hub | ||||
|       number: 0 | ||||
|       allow_other_uses: true | ||||
|       mode: OUTPUT | ||||
|     interlock: &interlock [gpio_switch1, gpio_switch2, gpio_switch3] | ||||
|   - platform: gpio | ||||
| @@ -409,7 +408,6 @@ switch: | ||||
|     pin: | ||||
|       mcp23xxx: mcp23008_hub | ||||
|       number: 0 | ||||
|       allow_other_uses: true | ||||
|       mode: OUTPUT | ||||
|     interlock: *interlock | ||||
|   - platform: gpio | ||||
|   | ||||
| @@ -92,3 +92,13 @@ sensor: | ||||
|       name: "Loop Time" | ||||
|     psram: | ||||
|       name: "PSRAM Free" | ||||
|  | ||||
| # Purposely test that `animation:` does auto-load `image:` | ||||
| # Keep the `image:` undefined. | ||||
| # image: | ||||
|  | ||||
| animation: | ||||
|   - id: rgb565_animation | ||||
|     file: pnglogo.png | ||||
|     type: RGB565 | ||||
|     use_transparency: no | ||||
|   | ||||
		Reference in New Issue
	
	Block a user