Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Handling HTTP Requests in Dahua Camera Integration #354

Open
pswel1 opened this issue May 11, 2024 · 3 comments
Open

Error Handling HTTP Requests in Dahua Camera Integration #354

pswel1 opened this issue May 11, 2024 · 3 comments

Comments

@pswel1
Copy link

pswel1 commented May 11, 2024

Encountering repeated ClientResponseError and HttpProcessingError with the Dahua camera integration in Home Assistant. Errors occur when attempting to fetch snapshots from the camera. The log indicates issues with parsing the HTTP response from the camera at /cgi-bin/snapshot.cgi. It appears the integration may not be handling certain HTTP response statuses or headers correctly. I'm a longtime fan, but out of my depth on potential fixes or updates needed in the integration code or camera settings.

Latest Dahua integration and HA 4/'24, using VTO2202F camera. Thanks for any help :)

2024-05-11 00:52:59.781 INFO (MainThread) [homeassistant.components.light] Setting up dahua.light
2024-05-11 00:52:59.782 WARNING (MainThread) [homeassistant.components.light] Entity None (<class 'custom_components.dahua.light.DahuaInfraredLight'>) is using deprecated supported features values which will be removed in HA Core 2025.1. Instead it should use <LightEntityFeature: 1> and color modes, please create a bug report at https://github.com/rroller/dahua/issues and reference https://developers.home-assistant.io/blog/2023/12/28/support-feature-magic-numbers-deprecation
2024-05-11 00:52:59.782 WARNING (MainThread) [homeassistant.components.light] None (<class 'custom_components.dahua.light.DahuaInfraredLight'>) does not set supported color modes, this will stop working in Home Assistant Core 2025.3, please create a bug report at https://github.com/rroller/dahua/issues

2024-05-11 00:55:30.896 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/aiohttp/client_proto.py", line 256, in data_received
    messages, upgraded, tail = self._parser.feed_data(data)
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "aiohttp/_http_parser.pyx", line 557, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadHttpMessage: 400, message:
  Data after `Connection: close`:
    b'HTTP/1.1 500 Internal Server Error'
       ^
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/aiohttp/client_reqrep.py", line 976, in start
    message, payload = await protocol.read()  # type: ignore[union-attr]
                       ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/streams.py", line 640, in read
    await self._waiter
aiohttp.http_exceptions.HttpProcessingError: 0, message:
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_protocol.py", line 452, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_app.py", line 543, in _handle
    resp = await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/web_middlewares.py", line 114, 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 83, 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 88, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp_session/__init__.py", line 199, in factory
    response = await handler(request)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 295, 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/camera/__init__.py", line 815, in get
    return await self.handle(request, camera)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/camera/__init__.py", line 833, in handle
    image = await _async_get_image(
            ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/camera/__init__.py", line 187, in _async_get_image
    else await camera.async_camera_image(width=width, height=height)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dahua/camera.py", line 253, in async_camera_image
    return await self._coordinator.client.async_get_snapshot(self._channel_number)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dahua/client.py", line 74, in async_get_snapshot
    return await self.get_bytes(url)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dahua/client.py", line 758, in get_bytes
    response = await auth.request("GET", self._base + url)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dahua/digest.py", line 46, in request
    response = await self.session.request(method, url, headers=headers, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 608, in _request
    await resp.start(conn)
  File "/usr/local/lib/python3.12/site-packages/aiohttp/client_reqrep.py", line 978, in start
    raise ClientResponseError(
aiohttp.client_exceptions.ClientResponseError: 0, message='', url=URL('http:https://192.168.xx.xx:80/cgi-bin/snapshot.cgi?channel=1')

@pswel1
Copy link
Author

pswel1 commented May 14, 2024

I cobbled together a ghetto fix to camera.py, the source of the error, basically giving it a chance to miss a couple times and perhaps spacing out API requests more. I don't know if it's a "fix" or a "workaround" so I probably won't do a PR, unless it's wanted

async def async_camera_image(self, width: int | None = None, height: int | None = None):
    """Return a still image response from the camera."""
    retries = 3                         
    delay = 0.25                                 
                                                    
    for attempt in range(retries):
        try:                                                                                                   
            # Try to fetch the snapshot    
            return await self._coordinator.client.async_get_snapshot(self._channel_number)
        except Exception as e:                       
            # Log the error with attempt count
            _LOGGER.warn(f"Attempt {attempt + 1} failed to get snapshot from channel {self._channel_number}: {str(e)}")
            # Wait before retrying                      
            if attempt < retries - 1:    
                await asyncio.sleep(delay)   
            else:                      
                _LOGGER.warn(f"All attempts failed; returning None")
                                               
    return None  # or perhaps a stock image could be used

clean logs for 24 hours so I'll call it "good enough" haha

@patelreese87
Copy link

Just here to say Thank You for the above. I was in a similar boat with same error basically. Trying out your code now. Hopefully the ghetto fix works long term :)

Thank you again

@mouldybread
Copy link

With regards to your specific issue, the HTTP/1.1 500 Internal Server Error when fetching snapshots is a broader issue that commonly affects Dahua-based IPCs. This fix helped me to resolve the same issue. If you happen to be using an NVR then fixing the camera resolves the issue on the NVR. I also reduced the snapshot generation time to two seconds to reduce the chance of an incomplete snapshot. Snapshots are now reliably generated.

It would though be nicer if this and the error encountered in #365 were handled more gracefully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants