mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Merge branch 'integration' into memory_api
This commit is contained in:
		| @@ -77,6 +77,7 @@ BRIGHTNESS = 0x51 | ||||
| WRDISBV = 0x51 | ||||
| RDDISBV = 0x52 | ||||
| WRCTRLD = 0x53 | ||||
| WCE = 0x58 | ||||
| SWIRE1 = 0x5A | ||||
| SWIRE2 = 0x5B | ||||
| IFMODE = 0xB0 | ||||
| @@ -91,6 +92,7 @@ PWCTR2 = 0xC1 | ||||
| PWCTR3 = 0xC2 | ||||
| PWCTR4 = 0xC3 | ||||
| PWCTR5 = 0xC4 | ||||
| SPIMODESEL = 0xC4 | ||||
| VMCTR1 = 0xC5 | ||||
| IFCTR = 0xC6 | ||||
| VMCTR2 = 0xC7 | ||||
|   | ||||
| @@ -5,10 +5,13 @@ from esphome.components.mipi import ( | ||||
|     PAGESEL, | ||||
|     PIXFMT, | ||||
|     SLPOUT, | ||||
|     SPIMODESEL, | ||||
|     SWIRE1, | ||||
|     SWIRE2, | ||||
|     TEON, | ||||
|     WCE, | ||||
|     WRAM, | ||||
|     WRCTRLD, | ||||
|     DriverChip, | ||||
|     delay, | ||||
| ) | ||||
| @@ -87,4 +90,19 @@ T4_S3_AMOLED = RM690B0.extend( | ||||
|     bus_mode=TYPE_QUAD, | ||||
| ) | ||||
|  | ||||
| CO5300 = DriverChip( | ||||
|     "CO5300", | ||||
|     brightness=0xD0, | ||||
|     color_order=MODE_RGB, | ||||
|     bus_mode=TYPE_QUAD, | ||||
|     initsequence=( | ||||
|         (SLPOUT,),  # Requires early SLPOUT | ||||
|         (PAGESEL, 0x00), | ||||
|         (SPIMODESEL, 0x80), | ||||
|         (WRCTRLD, 0x20), | ||||
|         (WCE, 0x00), | ||||
|     ), | ||||
| ) | ||||
|  | ||||
|  | ||||
| models = {} | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| from esphome.components.mipi import DriverChip | ||||
| import esphome.config_validation as cv | ||||
|  | ||||
| from .amoled import CO5300 | ||||
| from .ili import ILI9488_A | ||||
|  | ||||
| DriverChip( | ||||
| @@ -140,3 +141,14 @@ ILI9488_A.extend( | ||||
|     data_rate="20MHz", | ||||
|     invert_colors=True, | ||||
| ) | ||||
|  | ||||
| CO5300.extend( | ||||
|     "WAVESHARE-ESP32-S3-TOUCH-AMOLED-1.75", | ||||
|     width=466, | ||||
|     height=466, | ||||
|     pixel_mode="16bit", | ||||
|     offset_height=0, | ||||
|     offset_width=6, | ||||
|     cs_pin=12, | ||||
|     reset_pin=39, | ||||
| ) | ||||
|   | ||||
| @@ -373,3 +373,20 @@ button: | ||||
|     name: "Test Button" | ||||
|     on_press: | ||||
|       - logger.log: "Button pressed" | ||||
|  | ||||
| # Date, Time, and DateTime entities | ||||
| datetime: | ||||
|   - platform: template | ||||
|     type: date | ||||
|     name: "Test Date" | ||||
|     initial_value: "2023-05-13" | ||||
|     optimistic: true | ||||
|   - platform: template | ||||
|     type: time | ||||
|     name: "Test Time" | ||||
|     initial_value: "12:30:00" | ||||
|     optimistic: true | ||||
|   - platform: template | ||||
|     type: datetime | ||||
|     name: "Test DateTime" | ||||
|     optimistic: true | ||||
|   | ||||
| @@ -4,7 +4,17 @@ from __future__ import annotations | ||||
|  | ||||
| import asyncio | ||||
|  | ||||
| from aioesphomeapi import ClimateInfo, EntityState, SensorState | ||||
| from aioesphomeapi import ( | ||||
|     ClimateInfo, | ||||
|     DateInfo, | ||||
|     DateState, | ||||
|     DateTimeInfo, | ||||
|     DateTimeState, | ||||
|     EntityState, | ||||
|     SensorState, | ||||
|     TimeInfo, | ||||
|     TimeState, | ||||
| ) | ||||
| import pytest | ||||
|  | ||||
| from .types import APIClientConnectedFactory, RunCompiledFunction | ||||
| @@ -22,34 +32,56 @@ async def test_host_mode_many_entities( | ||||
|     async with run_compiled(yaml_config), api_client_connected() as client: | ||||
|         # Subscribe to state changes | ||||
|         states: dict[int, EntityState] = {} | ||||
|         sensor_count_future: asyncio.Future[int] = loop.create_future() | ||||
|         minimum_states_future: asyncio.Future[None] = loop.create_future() | ||||
|  | ||||
|         def on_state(state: EntityState) -> None: | ||||
|             states[state.key] = state | ||||
|             # Count sensor states specifically | ||||
|             # Check if we have received minimum expected states | ||||
|             sensor_states = [ | ||||
|                 s | ||||
|                 for s in states.values() | ||||
|                 if isinstance(s, SensorState) and isinstance(s.state, float) | ||||
|             ] | ||||
|             # When we have received states from at least 50 sensors, resolve the future | ||||
|             if len(sensor_states) >= 50 and not sensor_count_future.done(): | ||||
|                 sensor_count_future.set_result(len(sensor_states)) | ||||
|             date_states = [s for s in states.values() if isinstance(s, DateState)] | ||||
|             time_states = [s for s in states.values() if isinstance(s, TimeState)] | ||||
|             datetime_states = [ | ||||
|                 s for s in states.values() if isinstance(s, DateTimeState) | ||||
|             ] | ||||
|  | ||||
|             # We expect at least 50 sensors and 1 of each datetime entity type | ||||
|             if ( | ||||
|                 len(sensor_states) >= 50 | ||||
|                 and len(date_states) >= 1 | ||||
|                 and len(time_states) >= 1 | ||||
|                 and len(datetime_states) >= 1 | ||||
|                 and not minimum_states_future.done() | ||||
|             ): | ||||
|                 minimum_states_future.set_result(None) | ||||
|  | ||||
|         client.subscribe_states(on_state) | ||||
|  | ||||
|         # Wait for states from at least 50 sensors with timeout | ||||
|         # Wait for minimum states with timeout | ||||
|         try: | ||||
|             sensor_count = await asyncio.wait_for(sensor_count_future, timeout=10.0) | ||||
|             await asyncio.wait_for(minimum_states_future, timeout=10.0) | ||||
|         except TimeoutError: | ||||
|             sensor_states = [ | ||||
|                 s | ||||
|                 for s in states.values() | ||||
|                 if isinstance(s, SensorState) and isinstance(s.state, float) | ||||
|             ] | ||||
|             date_states = [s for s in states.values() if isinstance(s, DateState)] | ||||
|             time_states = [s for s in states.values() if isinstance(s, TimeState)] | ||||
|             datetime_states = [ | ||||
|                 s for s in states.values() if isinstance(s, DateTimeState) | ||||
|             ] | ||||
|  | ||||
|             pytest.fail( | ||||
|                 f"Did not receive states from at least 50 sensors within 10 seconds. " | ||||
|                 f"Received {len(sensor_states)} sensor states out of {len(states)} total states" | ||||
|                 f"Did not receive expected states within 10 seconds. " | ||||
|                 f"Received: {len(sensor_states)} sensor states (expected >=50), " | ||||
|                 f"{len(date_states)} date states (expected >=1), " | ||||
|                 f"{len(time_states)} time states (expected >=1), " | ||||
|                 f"{len(datetime_states)} datetime states (expected >=1). " | ||||
|                 f"Total states: {len(states)}" | ||||
|             ) | ||||
|  | ||||
|         # Verify we received a good number of entity states | ||||
| @@ -64,13 +96,25 @@ async def test_host_mode_many_entities( | ||||
|             if isinstance(s, SensorState) and isinstance(s.state, float) | ||||
|         ] | ||||
|  | ||||
|         assert sensor_count >= 50, ( | ||||
|             f"Expected at least 50 sensor states, got {sensor_count}" | ||||
|         ) | ||||
|         assert len(sensor_states) >= 50, ( | ||||
|             f"Expected at least 50 sensor states, got {len(sensor_states)}" | ||||
|         ) | ||||
|  | ||||
|         # Verify we received datetime entity states | ||||
|         date_states = [s for s in states.values() if isinstance(s, DateState)] | ||||
|         time_states = [s for s in states.values() if isinstance(s, TimeState)] | ||||
|         datetime_states = [s for s in states.values() if isinstance(s, DateTimeState)] | ||||
|  | ||||
|         assert len(date_states) >= 1, ( | ||||
|             f"Expected at least 1 date state, got {len(date_states)}" | ||||
|         ) | ||||
|         assert len(time_states) >= 1, ( | ||||
|             f"Expected at least 1 time state, got {len(time_states)}" | ||||
|         ) | ||||
|         assert len(datetime_states) >= 1, ( | ||||
|             f"Expected at least 1 datetime state, got {len(datetime_states)}" | ||||
|         ) | ||||
|  | ||||
|         # Get entity info to verify climate entity details | ||||
|         entities = await client.list_entities_services() | ||||
|         climate_infos = [e for e in entities[0] if isinstance(e, ClimateInfo)] | ||||
| @@ -89,3 +133,28 @@ async def test_host_mode_many_entities( | ||||
|         assert "HOME" in preset_names, f"Expected 'HOME' preset, got {preset_names}" | ||||
|         assert "AWAY" in preset_names, f"Expected 'AWAY' preset, got {preset_names}" | ||||
|         assert "SLEEP" in preset_names, f"Expected 'SLEEP' preset, got {preset_names}" | ||||
|  | ||||
|         # Verify datetime entities exist | ||||
|         date_infos = [e for e in entities[0] if isinstance(e, DateInfo)] | ||||
|         time_infos = [e for e in entities[0] if isinstance(e, TimeInfo)] | ||||
|         datetime_infos = [e for e in entities[0] if isinstance(e, DateTimeInfo)] | ||||
|  | ||||
|         assert len(date_infos) >= 1, "Expected at least 1 date entity" | ||||
|         assert len(time_infos) >= 1, "Expected at least 1 time entity" | ||||
|         assert len(datetime_infos) >= 1, "Expected at least 1 datetime entity" | ||||
|  | ||||
|         # Verify the entity names | ||||
|         date_info = date_infos[0] | ||||
|         assert date_info.name == "Test Date", ( | ||||
|             f"Expected date entity name 'Test Date', got {date_info.name}" | ||||
|         ) | ||||
|  | ||||
|         time_info = time_infos[0] | ||||
|         assert time_info.name == "Test Time", ( | ||||
|             f"Expected time entity name 'Test Time', got {time_info.name}" | ||||
|         ) | ||||
|  | ||||
|         datetime_info = datetime_infos[0] | ||||
|         assert datetime_info.name == "Test DateTime", ( | ||||
|             f"Expected datetime entity name 'Test DateTime', got {datetime_info.name}" | ||||
|         ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user