ITSpecialist111 / ai_automation_suggester

This custom Home Assistant integration periodically scans entities, detects new devices, and uses AI (via OpenAI's API) to suggest automations. It provides a user-friendly interface for accepting or rejecting automations, with placeholder entity mapping for privacy. This aims to enhance smart home automation via AI to identify new automations.
MIT License
7 stars 0 forks source link

TypeError: argument of type 'function' is not iterable #2

Closed tjorim closed 2 days ago

tjorim commented 2 days ago
Logger: aiohttp.server
Source: /usr/local/lib/python3.12/site-packages/aiohttp/web_protocol.py:448
First occurred: 21:53:34 (3 occurrences)
Last logged: 21:57:58

Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_protocol.py", line 477, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_app.py", line 559, in _handle
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 92, in security_filter_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 77, in forwarded_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 26, in request_context_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 85, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 242, in auth_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 32, in headers_middleware
    response = await handler(request)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 73, in handle
    result = await handler(request, **request.match_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/decorators.py", line 81, in with_admin
    return await func(self, request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 222, in post
    return await super().post(request, flow_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 74, in wrapper
    return await method(view, request, data, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 122, in post
    result = await self._flow_mgr.async_configure(flow_id, data)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 370, in async_configure
    result = await self._async_configure(flow_id, user_input)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 417, in _async_configure
    result = await self._async_handle_step(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 575, in _async_handle_step
    result = await self.async_finish_flow(flow, result.copy())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1484, in async_finish_flow
    await self.config_entries.async_add(entry)
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1821, in async_add
    await self.async_setup(entry.entry_id)
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1937, in async_setup
    result = await async_setup_component(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/setup.py", line 159, in async_setup_component
    return await existing_setup_future
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: argument of type 'function' is not iterable
tjorim commented 2 days ago

Seems like that error happens only when trying again. When deleting all entries and restarting HA, this is the first error I get trying to set it up:

Logger: aiohttp.server
Source: /usr/local/lib/python3.12/site-packages/aiohttp/web_protocol.py:448
First occurred: 22:11:07 (1 occurrences)
Last logged: 22:11:07

Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_protocol.py", line 477, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_app.py", line 559, in _handle
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 92, in security_filter_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 77, in forwarded_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 26, in request_context_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 85, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 242, in auth_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 32, in headers_middleware
    response = await handler(request)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 73, in handle
    result = await handler(request, **request.match_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/decorators.py", line 81, in with_admin
    return await func(self, request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 222, in post
    return await super().post(request, flow_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 74, in wrapper
    return await method(view, request, data, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 122, in post
    result = await self._flow_mgr.async_configure(flow_id, data)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 370, in async_configure
    result = await self._async_configure(flow_id, user_input)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 417, in _async_configure
    result = await self._async_handle_step(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 575, in _async_handle_step
    result = await self.async_finish_flow(flow, result.copy())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1484, in async_finish_flow
    await self.config_entries.async_add(entry)
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1821, in async_add
    await self.async_setup(entry.entry_id)
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1937, in async_setup
    result = await async_setup_component(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/setup.py", line 185, in async_setup_component
    await future
  File "/usr/src/homeassistant/homeassistant/setup.py", line 165, in async_setup_component
    result = await _async_setup_component(hass, domain, config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/setup.py", line 343, in _async_setup_component
    processed_config = conf_util.async_drop_config_annotations(
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/config.py", line 1268, in async_drop_config_annotations
    if integration.domain in config and integration.domain != HOMEASSISTANT_DOMAIN:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: argument of type 'function' is not iterable
ITSpecialist111 commented 2 days ago

Thanks for the update - I'm on it

ITSpecialist111 commented 2 days ago

Code Updated to V1.02 to resolve the following:

Problem Summary

The integration setup was failing during the OpenAI API key entry step in the UI, with the error message indicating an unknown issue or connection failure. The failure was traced to changes in the config_flow.py and init.py files that were introducing additional validation and configuration requirements.

Solution Breakdown

The following steps resolved the issue:

Revert config_flow.py to the Old Version:

The new version of config_flow.py contained more rigorous validation for the OpenAI API key, including a direct validation call (validate_openai_api_key) which caused errors when setting up the integration.

To resolve this, the entire config_flow.py was reverted to the old version, which simply checked if the OpenAI API key was provided without additional validation during setup.

Key Changes in config_flow.py:

Removed additional API key validation logic that attempted to contact OpenAI's servers during the setup process.

This removed the need for handling API errors during the initial configuration flow, which simplified the setup process and prevented connection issues from blocking the integration.

Remove CONFIG_SCHEMA from init.py:

The new version of init.py contained the line: CONFIG_SCHEMA = cv.config_entry_only_config_schema. This introduced stricter schema validation requirements, which caused issues during integration setup.

Removing this line allowed the integration to avoid unnecessary validation checks, making it more flexible during the configuration phase.

Update coordinator.py API Call:

In the new version, the API call to OpenAI was using response = openai.chat.completions.create(...), which caused an error.

Reverting this line to the old version (response = openai.Engine.list()) resolved the issue and allowed the integration to connect to the OpenAI API successfully.

Result

After applying the above changes, the integration was able to successfully complete the setup without errors. The removal of the additional validation logic and configuration schema requirements simplified the setup process, ensuring compatibility with the current Home Assistant setup.

Steps to Apply the Fix

Replace config_flow.py:

Use the old working version of config_flow.py that does not include extra API key validation.

Edit init.py:

Remove the line: CONFIG_SCHEMA = cv.config_entry_only_config_schema.

Edit coordinator.py:

Change the line of code responsible for creating the OpenAI API request back to the old version: response = openai.Engine.list().

These changes should fix the 'unknown error' during setup and allow the integration to function as expected.