mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Merge branch 'dev' into multi_device
This commit is contained in:
		| @@ -26,3 +26,17 @@ binary_sensor: | ||||
|     threshold: 100 | ||||
|     filters: | ||||
|       - invert: | ||||
|   - platform: analog_threshold | ||||
|     name: Analog Threshold 3 | ||||
|     sensor_id: template_sensor | ||||
|     threshold: !lambda return 100; | ||||
|     filters: | ||||
|       - invert: | ||||
|   - platform: analog_threshold | ||||
|     name: Analog Threshold 4 | ||||
|     sensor_id: template_sensor | ||||
|     threshold: | ||||
|       upper: !lambda return 110; | ||||
|       lower: !lambda return 90; | ||||
|     filters: | ||||
|       - invert: | ||||
|   | ||||
							
								
								
									
										10
									
								
								tests/components/api/test-dynamic-encryption.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/components/api/test-dynamic-encryption.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| packages: | ||||
|   common: !include common.yaml | ||||
|  | ||||
| wifi: | ||||
|   ssid: MySSID | ||||
|   password: password1 | ||||
|  | ||||
| api: | ||||
|   encryption: | ||||
|     key: !remove | ||||
							
								
								
									
										71
									
								
								tests/components/mapping/common.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								tests/components/mapping/common.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| image: | ||||
|   grayscale: | ||||
|     alpha_channel: | ||||
|       - file: ../../pnglogo.png | ||||
|         id: image_1 | ||||
|         resize: 50x50 | ||||
|       - file: ../../pnglogo.png | ||||
|         id: image_2 | ||||
|         resize: 50x50 | ||||
|  | ||||
| mapping: | ||||
|   - id: weather_map | ||||
|     from: string | ||||
|     to: "image::Image" | ||||
|     entries: | ||||
|       clear-night: image_1 | ||||
|       sunny: image_2 | ||||
|   - id: weather_map_1 | ||||
|     from: string | ||||
|     to: esphome::image::Image | ||||
|     entries: | ||||
|       clear-night: image_1 | ||||
|       sunny: image_2 | ||||
|   - id: weather_map_2 | ||||
|     from: string | ||||
|     to: image | ||||
|     entries: | ||||
|       clear-night: image_1 | ||||
|       sunny: image_2 | ||||
|   - id: int_map | ||||
|     from: int | ||||
|     to: string | ||||
|     entries: | ||||
|       1: "one" | ||||
|       2: "two" | ||||
|       3: "three" | ||||
|       77: "seventy-seven" | ||||
|   - id: string_map | ||||
|     from: string | ||||
|     to: int | ||||
|     entries: | ||||
|       one: 1 | ||||
|       two: 2 | ||||
|       three: 3 | ||||
|       seventy-seven: 77 | ||||
|   - id: color_map | ||||
|     from: string | ||||
|     to: color | ||||
|     entries: | ||||
|       red: red_id | ||||
|       blue: blue_id | ||||
|       green: green_id | ||||
|  | ||||
| color: | ||||
|   - id: red_id | ||||
|     red: 1.0 | ||||
|     green: 0.0 | ||||
|     blue: 0.0 | ||||
|   - id: green_id | ||||
|     red: 0.0 | ||||
|     green: 1.0 | ||||
|     blue: 0.0 | ||||
|   - id: blue_id | ||||
|     red: 0.0 | ||||
|     green: 0.0 | ||||
|     blue: 1.0 | ||||
|  | ||||
| display: | ||||
|   lambda: |- | ||||
|       it.image(0, 0, id(weather_map)[0]); | ||||
|       it.image(0, 100, id(weather_map)[1]); | ||||
							
								
								
									
										17
									
								
								tests/components/mapping/test.esp32-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/mapping/test.esp32-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| spi: | ||||
|   - id: spi_main_lcd | ||||
|     clk_pin: 16 | ||||
|     mosi_pin: 17 | ||||
|     miso_pin: 15 | ||||
|  | ||||
| display: | ||||
|   - platform: ili9xxx | ||||
|     id: main_lcd | ||||
|     model: ili9342 | ||||
|     cs_pin: 12 | ||||
|     dc_pin: 13 | ||||
|     reset_pin: 21 | ||||
|     invert_colors: false | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										17
									
								
								tests/components/mapping/test.esp32-c3-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/mapping/test.esp32-c3-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| spi: | ||||
|   - id: spi_main_lcd | ||||
|     clk_pin: 6 | ||||
|     mosi_pin: 7 | ||||
|     miso_pin: 5 | ||||
|  | ||||
| display: | ||||
|   - platform: ili9xxx | ||||
|     id: main_lcd | ||||
|     model: ili9342 | ||||
|     cs_pin: 8 | ||||
|     dc_pin: 9 | ||||
|     reset_pin: 10 | ||||
|     invert_colors: false | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										17
									
								
								tests/components/mapping/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/mapping/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| spi: | ||||
|   - id: spi_main_lcd | ||||
|     clk_pin: 6 | ||||
|     mosi_pin: 7 | ||||
|     miso_pin: 5 | ||||
|  | ||||
| display: | ||||
|   - platform: ili9xxx | ||||
|     id: main_lcd | ||||
|     model: ili9342 | ||||
|     cs_pin: 8 | ||||
|     dc_pin: 9 | ||||
|     reset_pin: 10 | ||||
|     invert_colors: false | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										17
									
								
								tests/components/mapping/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/mapping/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| spi: | ||||
|   - id: spi_main_lcd | ||||
|     clk_pin: 16 | ||||
|     mosi_pin: 17 | ||||
|     miso_pin: 15 | ||||
|  | ||||
| display: | ||||
|   - platform: ili9xxx | ||||
|     id: main_lcd | ||||
|     model: ili9342 | ||||
|     cs_pin: 12 | ||||
|     dc_pin: 13 | ||||
|     reset_pin: 21 | ||||
|     invert_colors: false | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										17
									
								
								tests/components/mapping/test.esp8266-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/mapping/test.esp8266-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| spi: | ||||
|   - id: spi_main_lcd | ||||
|     clk_pin: 14 | ||||
|     mosi_pin: 13 | ||||
|     miso_pin: 12 | ||||
|  | ||||
| display: | ||||
|   - platform: ili9xxx | ||||
|     id: main_lcd | ||||
|     model: ili9342 | ||||
|     cs_pin: 5 | ||||
|     dc_pin: 15 | ||||
|     reset_pin: 16 | ||||
|     invert_colors: false | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										12
									
								
								tests/components/mapping/test.host.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/components/mapping/test.host.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| display: | ||||
|   - platform: sdl | ||||
|     id: sdl_display | ||||
|     update_interval: 1s | ||||
|     auto_clear_enabled: false | ||||
|     show_test_card: true | ||||
|     dimensions: | ||||
|       width: 450 | ||||
|       height: 600 | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										17
									
								
								tests/components/mapping/test.rp2040-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/mapping/test.rp2040-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| spi: | ||||
|   - id: spi_main_lcd | ||||
|     clk_pin: 2 | ||||
|     mosi_pin: 3 | ||||
|     miso_pin: 4 | ||||
|  | ||||
| display: | ||||
|   - platform: ili9xxx | ||||
|     id: main_lcd | ||||
|     model: ili9342 | ||||
|     cs_pin: 20 | ||||
|     dc_pin: 21 | ||||
|     reset_pin: 22 | ||||
|     invert_colors: false | ||||
|  | ||||
| packages: | ||||
|   map: !include common.yaml | ||||
							
								
								
									
										13
									
								
								tests/components/pm2005/common.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/components/pm2005/common.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| i2c: | ||||
|   - id: i2c_pm2005 | ||||
|     scl: ${scl_pin} | ||||
|     sda: ${sda_pin} | ||||
|  | ||||
| sensor: | ||||
|   - platform: pm2005 | ||||
|     pm_1_0: | ||||
|       name: PM1.0 | ||||
|     pm_2_5: | ||||
|       name: PM2.5 | ||||
|     pm_10_0: | ||||
|       name: PM10.0 | ||||
							
								
								
									
										5
									
								
								tests/components/pm2005/test.esp32-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/pm2005/test.esp32-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| substitutions: | ||||
|   scl_pin: GPIO16 | ||||
|   sda_pin: GPIO17 | ||||
|  | ||||
| <<: !include common.yaml | ||||
							
								
								
									
										5
									
								
								tests/components/pm2005/test.esp32-c3-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/pm2005/test.esp32-c3-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| substitutions: | ||||
|   scl_pin: GPIO5 | ||||
|   sda_pin: GPIO4 | ||||
|  | ||||
| <<: !include common.yaml | ||||
							
								
								
									
										5
									
								
								tests/components/pm2005/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/pm2005/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| substitutions: | ||||
|   scl_pin: GPIO5 | ||||
|   sda_pin: GPIO4 | ||||
|  | ||||
| <<: !include common.yaml | ||||
							
								
								
									
										5
									
								
								tests/components/pm2005/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/pm2005/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| substitutions: | ||||
|   scl_pin: GPIO16 | ||||
|   sda_pin: GPIO17 | ||||
|  | ||||
| <<: !include common.yaml | ||||
							
								
								
									
										5
									
								
								tests/components/pm2005/test.esp8266-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/pm2005/test.esp8266-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| substitutions: | ||||
|   scl_pin: GPIO5 | ||||
|   sda_pin: GPIO4 | ||||
|  | ||||
| <<: !include common.yaml | ||||
							
								
								
									
										5
									
								
								tests/components/pm2005/test.rp2040-ard.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/pm2005/test.rp2040-ard.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| substitutions: | ||||
|   scl_pin: GPIO5 | ||||
|   sda_pin: GPIO4 | ||||
|  | ||||
| <<: !include common.yaml | ||||
| @@ -1,6 +1,3 @@ | ||||
| substitutions: | ||||
|   verify_ssl: "false" | ||||
|  | ||||
| esphome: | ||||
|   name: livingroomdevice | ||||
|   friendly_name: Living Room Device | ||||
| @@ -129,6 +126,14 @@ valve: | ||||
|     optimistic: true | ||||
|     has_position: true | ||||
|  | ||||
| remote_transmitter: | ||||
|   pin: ${pin} | ||||
|   carrier_duty_percent: 50% | ||||
|  | ||||
| climate: | ||||
|   - platform: climate_ir_lg | ||||
|     name: LG Climate | ||||
|  | ||||
| prometheus: | ||||
|   include_internal: true | ||||
|   relabel: | ||||
|   | ||||
| @@ -1,3 +1,7 @@ | ||||
| substitutions: | ||||
|   verify_ssl: "false" | ||||
|   pin: GPIO5 | ||||
|  | ||||
| <<: !include common.yaml | ||||
|  | ||||
| i2s_audio: | ||||
|   | ||||
| @@ -1 +1,5 @@ | ||||
| substitutions: | ||||
|   verify_ssl: "false" | ||||
|   pin: GPIO2 | ||||
|  | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1 +1,5 @@ | ||||
| substitutions: | ||||
|   verify_ssl: "false" | ||||
|   pin: GPIO2 | ||||
|  | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1 +1,5 @@ | ||||
| substitutions: | ||||
|   verify_ssl: "false" | ||||
|   pin: GPIO2 | ||||
|  | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1 +1,5 @@ | ||||
| substitutions: | ||||
|   verify_ssl: "false" | ||||
|   pin: GPIO5 | ||||
|  | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -17,3 +17,13 @@ sensor: | ||||
| text_sensor: | ||||
|   - platform: uptime | ||||
|     name: Uptime Text | ||||
|   - platform: uptime | ||||
|     name: Uptime Text With Separator | ||||
|     format: | ||||
|       separator: "-" | ||||
|       expand: true | ||||
|       days: "Days" | ||||
|       hours: "H" | ||||
|       minutes: "M" | ||||
|       seconds: "S" | ||||
|     update_interval: 10s | ||||
|   | ||||
| @@ -267,3 +267,13 @@ def test_sanitize(text, expected): | ||||
|     actual = helpers.sanitize(text) | ||||
|  | ||||
|     assert actual == expected | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "text, expected", | ||||
|     ((["127.0.0.1", "fe80::1", "2001::2"], ["2001::2", "127.0.0.1", "fe80::1"]),), | ||||
| ) | ||||
| def test_sort_ip_addresses(text: list[str], expected: list[str]) -> None: | ||||
|     actual = helpers.sort_ip_addresses(text) | ||||
|  | ||||
|     assert actual == expected | ||||
|   | ||||
							
								
								
									
										125
									
								
								tests/unit_tests/test_vscode.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								tests/unit_tests/test_vscode.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| import json | ||||
| import os | ||||
| from unittest.mock import Mock, patch | ||||
|  | ||||
| from esphome import vscode | ||||
|  | ||||
|  | ||||
| def _run_repl_test(input_data): | ||||
|     """Reusable test function for different input scenarios.""" | ||||
|     input_data.append(_exit()) | ||||
|     with ( | ||||
|         patch("builtins.input", side_effect=input_data), | ||||
|         patch("sys.stdout") as mock_stdout, | ||||
|     ): | ||||
|         args = Mock([]) | ||||
|         args.ace = False | ||||
|         args.substitution = None | ||||
|         vscode.read_config(args) | ||||
|  | ||||
|         # Capture printed output | ||||
|         full_output = "".join(call[0][0] for call in mock_stdout.write.call_args_list) | ||||
|         return full_output.strip().split("\n") | ||||
|  | ||||
|  | ||||
| def _validate(file_path: str): | ||||
|     return json.dumps({"type": "validate", "file": file_path}) | ||||
|  | ||||
|  | ||||
| def _file_response(data: str): | ||||
|     return json.dumps({"type": "file_response", "content": data}) | ||||
|  | ||||
|  | ||||
| def _read_file(file_path: str): | ||||
|     return json.dumps({"type": "read_file", "path": file_path}) | ||||
|  | ||||
|  | ||||
| def _exit(): | ||||
|     return json.dumps({"type": "exit"}) | ||||
|  | ||||
|  | ||||
| RESULT_NO_ERROR = '{"type": "result", "yaml_errors": [], "validation_errors": []}' | ||||
|  | ||||
|  | ||||
| def test_multi_file(): | ||||
|     source_path = os.path.join("dir_path", "x.yaml") | ||||
|     output_lines = _run_repl_test( | ||||
|         [ | ||||
|             _validate(source_path), | ||||
|             # read_file x.yaml | ||||
|             _file_response("""esphome: | ||||
|   name: test1 | ||||
| esp8266: | ||||
|   board: !secret my_secret_board | ||||
| """), | ||||
|             # read_file secrets.yaml | ||||
|             _file_response("""my_secret_board: esp1f"""), | ||||
|         ] | ||||
|     ) | ||||
|  | ||||
|     expected_lines = [ | ||||
|         _read_file(source_path), | ||||
|         _read_file(os.path.join("dir_path", "secrets.yaml")), | ||||
|         RESULT_NO_ERROR, | ||||
|     ] | ||||
|  | ||||
|     assert output_lines == expected_lines | ||||
|  | ||||
|  | ||||
| def test_shows_correct_range_error(): | ||||
|     source_path = os.path.join("dir_path", "x.yaml") | ||||
|     output_lines = _run_repl_test( | ||||
|         [ | ||||
|             _validate(source_path), | ||||
|             # read_file x.yaml | ||||
|             _file_response("""esphome: | ||||
|   name: test1 | ||||
| esp8266: | ||||
|   broad: !secret my_secret_board        # typo here | ||||
| """), | ||||
|             # read_file secrets.yaml | ||||
|             _file_response("""my_secret_board: esp1f"""), | ||||
|         ] | ||||
|     ) | ||||
|  | ||||
|     assert len(output_lines) == 3 | ||||
|     error = json.loads(output_lines[2]) | ||||
|     validation_error = error["validation_errors"][0] | ||||
|     assert validation_error["message"].startswith("[broad] is an invalid option for") | ||||
|     range = validation_error["range"] | ||||
|     assert range["document"] == source_path | ||||
|     assert range["start_line"] == 3 | ||||
|     assert range["start_col"] == 2 | ||||
|     assert range["end_line"] == 3 | ||||
|     assert range["end_col"] == 7 | ||||
|  | ||||
|  | ||||
| def test_shows_correct_loaded_file_error(): | ||||
|     source_path = os.path.join("dir_path", "x.yaml") | ||||
|     output_lines = _run_repl_test( | ||||
|         [ | ||||
|             _validate(source_path), | ||||
|             # read_file x.yaml | ||||
|             _file_response("""esphome: | ||||
|   name: test1 | ||||
|  | ||||
| packages: | ||||
|   board: !include .pkg.esp8266.yaml | ||||
| """), | ||||
|             # read_file .pkg.esp8266.yaml | ||||
|             _file_response("""esp8266: | ||||
|   broad: esp1f # typo here | ||||
| """), | ||||
|         ] | ||||
|     ) | ||||
|  | ||||
|     assert len(output_lines) == 3 | ||||
|     error = json.loads(output_lines[2]) | ||||
|     validation_error = error["validation_errors"][0] | ||||
|     assert validation_error["message"].startswith("[broad] is an invalid option for") | ||||
|     range = validation_error["range"] | ||||
|     assert range["document"] == os.path.join("dir_path", ".pkg.esp8266.yaml") | ||||
|     assert range["start_line"] == 1 | ||||
|     assert range["start_col"] == 2 | ||||
|     assert range["end_line"] == 1 | ||||
|     assert range["end_col"] == 7 | ||||
| @@ -42,3 +42,23 @@ def test_loading_a_missing_file(fixture_path): | ||||
|         yaml_util.load_yaml(yaml_file) | ||||
|     except EsphomeError as err: | ||||
|         assert "missing.yaml" in str(err) | ||||
|  | ||||
|  | ||||
| def test_parsing_with_custom_loader(fixture_path): | ||||
|     """Test custom loader used for vscode connection | ||||
|     Default loader is tested in test_include_with_vars | ||||
|     """ | ||||
|     yaml_file = fixture_path / "yaml_util" / "includetest.yaml" | ||||
|  | ||||
|     loader_calls = [] | ||||
|  | ||||
|     def custom_loader(fname): | ||||
|         loader_calls.append(fname) | ||||
|  | ||||
|     with open(yaml_file, encoding="utf-8") as f_handle: | ||||
|         yaml_util.parse_yaml(yaml_file, f_handle, custom_loader) | ||||
|  | ||||
|     assert len(loader_calls) == 3 | ||||
|     assert loader_calls[0].endswith("includes/included.yaml") | ||||
|     assert loader_calls[1].endswith("includes/list.yaml") | ||||
|     assert loader_calls[2].endswith("includes/scalar.yaml") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user