mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[api] Fix compilation error with char* lambdas in HomeAssistant services (#9638)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
		| @@ -60,5 +60,28 @@ api: | ||||
|             data: | ||||
|               value: !lambda 'return input_float;' | ||||
|  | ||||
|     # Service that tests char* lambda functionality (e.g., from itoa or sprintf) | ||||
|     - action: test_char_ptr_lambda | ||||
|       variables: | ||||
|         input_number: int | ||||
|         input_string: string | ||||
|       then: | ||||
|         # Log the input to verify service was called | ||||
|         - logger.log: | ||||
|             format: "Service called with number for char* test: %d" | ||||
|             args: [input_number] | ||||
|  | ||||
|         # Test that char* lambdas work correctly | ||||
|         # This would fail in issue #9628 with "invalid conversion from 'char*' to 'long long unsigned int'" | ||||
|         - homeassistant.event: | ||||
|             event: esphome.test_char_ptr_lambda | ||||
|             data: | ||||
|               # Test snprintf returning char* | ||||
|               decimal_value: !lambda 'static char buffer[20]; snprintf(buffer, sizeof(buffer), "%d", input_number); return buffer;' | ||||
|               # Test strdup returning char* (dynamically allocated) | ||||
|               string_copy: !lambda 'return strdup(input_string.c_str());' | ||||
|               # Test string literal (const char*) | ||||
|               literal: !lambda 'return "test literal";' | ||||
|  | ||||
| logger: | ||||
|   level: DEBUG | ||||
|   | ||||
| @@ -19,15 +19,17 @@ async def test_api_string_lambda( | ||||
|     """Test TemplatableStringValue works with lambdas that return different types.""" | ||||
|     loop = asyncio.get_running_loop() | ||||
|  | ||||
|     # Track log messages for all three service calls | ||||
|     # Track log messages for all four service calls | ||||
|     string_called_future = loop.create_future() | ||||
|     int_called_future = loop.create_future() | ||||
|     float_called_future = loop.create_future() | ||||
|     char_ptr_called_future = loop.create_future() | ||||
|  | ||||
|     # Patterns to match in logs - confirms the lambdas compiled and executed | ||||
|     string_pattern = re.compile(r"Service called with string: STRING_FROM_LAMBDA") | ||||
|     int_pattern = re.compile(r"Service called with int: 42") | ||||
|     float_pattern = re.compile(r"Service called with float: 3\.14") | ||||
|     char_ptr_pattern = re.compile(r"Service called with number for char\* test: 123") | ||||
|  | ||||
|     def check_output(line: str) -> None: | ||||
|         """Check log output for expected messages.""" | ||||
| @@ -37,6 +39,8 @@ async def test_api_string_lambda( | ||||
|             int_called_future.set_result(True) | ||||
|         if not float_called_future.done() and float_pattern.search(line): | ||||
|             float_called_future.set_result(True) | ||||
|         if not char_ptr_called_future.done() and char_ptr_pattern.search(line): | ||||
|             char_ptr_called_future.set_result(True) | ||||
|  | ||||
|     # Run with log monitoring | ||||
|     async with ( | ||||
| @@ -65,17 +69,28 @@ async def test_api_string_lambda( | ||||
|         ) | ||||
|         assert float_service is not None, "test_float_lambda service not found" | ||||
|  | ||||
|         # Execute all three services to test different lambda return types | ||||
|         char_ptr_service = next( | ||||
|             (s for s in services if s.name == "test_char_ptr_lambda"), None | ||||
|         ) | ||||
|         assert char_ptr_service is not None, "test_char_ptr_lambda service not found" | ||||
|  | ||||
|         # Execute all four services to test different lambda return types | ||||
|         client.execute_service(string_service, {"input_string": "STRING_FROM_LAMBDA"}) | ||||
|         client.execute_service(int_service, {"input_number": 42}) | ||||
|         client.execute_service(float_service, {"input_float": 3.14}) | ||||
|         client.execute_service( | ||||
|             char_ptr_service, {"input_number": 123, "input_string": "test_string"} | ||||
|         ) | ||||
|  | ||||
|         # Wait for all service log messages | ||||
|         # This confirms the lambdas compiled successfully and executed | ||||
|         try: | ||||
|             await asyncio.wait_for( | ||||
|                 asyncio.gather( | ||||
|                     string_called_future, int_called_future, float_called_future | ||||
|                     string_called_future, | ||||
|                     int_called_future, | ||||
|                     float_called_future, | ||||
|                     char_ptr_called_future, | ||||
|                 ), | ||||
|                 timeout=5.0, | ||||
|             ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user