JeffSteinbok / hass-dreo

Dreo Smart Device Integration for Home Assistant
MIT License
90 stars 28 forks source link

Error using Home Assistant 2024.5 #87

Closed user-08-151 closed 1 month ago

user-08-151 commented 2 months ago

I'm getting following error when trying to power on a Dreao fan from a dashboard:

2024-05-02 12:21:26.223 WARNING (DreoWebSocketStream) [homeassistant.helpers.frame] Detected that custom integration 'dreo' calls async_create_task from a thread at custom_components/dreo/basedevice.py, line 54: self.async_schedule_update_ha_state(True), please report it to the author of the 'dreo' custom integration
2024-05-02 12:21:26.224 ERROR (DreoWebSocketStream) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/dreo/pydreo/commandtransport.py", line 129, in _ws_consumer_handler
    self._ws_consume_message(json.loads(message))
  File "/config/custom_components/dreo/pydreo/commandtransport.py", line 161, in _ws_consume_message
    self._recv_callback(message)
  File "/config/custom_components/dreo/pydreo/__init__.py", line 324, in _transport_consume_message
    device.handle_server_update_base(message)
  File "/config/custom_components/dreo/pydreo/pydreobasedevice.py", line 79, in handle_server_update_base
    self._do_callbacks()
  File "/config/custom_components/dreo/pydreo/pydreobasedevice.py", line 117, in _do_callbacks
    cb()
  File "/config/custom_components/dreo/basedevice.py", line 54, in update_state
    self.async_schedule_update_ha_state(True)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1252, in async_schedule_update_ha_state
    self.hass.async_create_task(
  File "/usr/src/homeassistant/homeassistant/core.py", line 816, in async_create_task
    self.verify_event_loop_thread("async_create_task")
  File "/usr/src/homeassistant/homeassistant/core.py", line 440, in verify_event_loop_thread
    frame.report(
  File "/usr/src/homeassistant/homeassistant/helpers/frame.py", line 162, in report
    _report_integration(what, integration_frame, level, error_if_integration)
  File "/usr/src/homeassistant/homeassistant/helpers/frame.py", line 203, in _report_integration
    raise RuntimeError(
RuntimeError: Detected that custom integration 'dreo' calls async_create_task from a thread at custom_components/dreo/basedevice.py, line 54: self.async_schedule_update_ha_state(True). Please report it to the author of the 'dreo' custom integration.
2024-05-02 12:21:26.232 WARNING (DreoWebSocketStream) [py.warnings] /config/custom_components/dreo/pydreo/commandtransport.py:101: RuntimeWarning: coroutine 'Entity.async_update_ha_state' was never awaited
  await self._ws_handler(ws)

While the fan is started the state is never updated within Home Assistant.

The issue seems to be solved when replacing the call of the async method (https://github.com/JeffSteinbok/hass-dreo/blob/main/custom_components/dreo/basedevice.py#L53) with the sync one self.schedule_update_ha_state(True) - but since I'm not too familiar with Home Assistant, I'm not sure if that is the right solution.

QuiNz0r commented 2 months ago

image

matthewbogner commented 2 months ago

I have the same issue as reported above. Based on a similar report in the tuya-local integration, I suspect there was some change in the APIs with the latest HA release.

https://community.home-assistant.io/t/2024-4-4-2024-5-0-issue-stuck-on-home-assistant-is-starting/724779/4

https://github.com/make-all/tuya-local/issues/1871

https://community.home-assistant.io/t/custom-component-hp-printer/147127/303?page=16

PHolstein1 commented 2 months ago

I'm getting the same error. According to Google's Gemini, here is the issue:

Background Tasks: Home Assistant uses asynchronous programming to manage different tasks efficiently. The async_create_task function is meant to be used within the main Home Assistant event loop for proper scheduling and execution.

The Problem: The 'dreo' integration seems to be calling async_create_task from a separate thread. This can lead to unexpected behavior, potential conflicts with Home Assistant's internal processes, and issues with the integration itself

The last line of the traceback pinpoints the exact problem: custom_components/dreo/basedevice.py, line 53, where the async_schedule_update_ha_state(True) call is being made within a thread.

Solution

Temporary Workaround: Potentially attempt a temporary edit in custom_components/dreo/basedevice.py, line 53, if necessary. However, proceed with extreme caution and create backups.

VOSsec commented 2 months ago

How to fix the problem yourself for the first time

  1. Make a full Home Assistant backup
  2. Using Visual Studio Code, edit custom_components/dreo/basedevice.py
  3. Replace the entire code with my code
  4. Restart Home Assistant
  5. Have fun 😘
  6. Nevertheless, install @JeffSteinbok 's hotfix as soon as it is available πŸ˜‰
"""BaseDevice utilities for Dreo Component."""
import logging

from .pydreo.pydreobasedevice import PyDreoBaseDevice
from .haimports import * # pylint: disable=W0401,W0614

from .const import (
    LOGGER,
    DOMAIN
)

_LOGGER = logging.getLogger(LOGGER)

class DreoBaseDeviceHA(Entity):
    """Base class for Dreo Entity Representations."""

    def __init__(self, pydreo_base_device: PyDreoBaseDevice) -> None:
        """Initialize the Dreo device."""
        self.device = pydreo_base_device
        self._attr_unique_id = self.device.sn
        self._attr_name = pydreo_base_device.name

    @property
    def device_info(self) -> DeviceInfo:
        """Return the device info."""

        return DeviceInfo(
            identifiers={
                # Serial numbers are unique identifiers within a specific domain
                (DOMAIN, self.device.sn)
            },
            name=self.device.name,
            manufacturer="Dreo",
            model=self.device.model
        )

    @property
    def available(self) -> bool:
        """Return True if device is available."""
        # return self.device.connection_status == "online"
        return True

    @property
    def should_poll(self):
        return False

    def async_added_to_hass(self):
        """Register callbacks."""

        def update_state():
            # Tell HA we're ready to update
            self.schedule_update_ha_state(True)

        self.device.add_attr_callback(update_state)
PHolstein1 commented 2 months ago

How to fix the problem yourself for the first time

  1. Make a full Home Assistant backup

Thanks for doing this. This worked out great for me.

VOSsec commented 1 month ago

How to fix the problem yourself for the first time

  1. Make a full Home Assistant backup
  2. Using Visual Studio Code, edit custom_components/dreo/basedevice.py
  3. Replace the entire code with my code
  4. Restart Home Assistant
  5. Have fun 😘
  6. Nevertheless, install @JeffSteinbok 's hotfix as soon as it is available πŸ˜‰
"""BaseDevice utilities for Dreo Component."""
import logging

from .pydreo.pydreobasedevice import PyDreoBaseDevice
from .haimports import * # pylint: disable=W0401,W0614

from .const import (
    LOGGER,
    DOMAIN
)

_LOGGER = logging.getLogger(LOGGER)

class DreoBaseDeviceHA(Entity):
    """Base class for Dreo Entity Representations."""

    def __init__(self, pydreo_base_device: PyDreoBaseDevice) -> None:
        """Initialize the Dreo device."""
        self.device = pydreo_base_device
        self._attr_unique_id = self.device.sn
        self._attr_name = pydreo_base_device.name

    @property
    def device_info(self) -> DeviceInfo:
        """Return the device info."""

        return DeviceInfo(
            identifiers={
                # Serial numbers are unique identifiers within a specific domain
                (DOMAIN, self.device.sn)
            },
            name=self.device.name,
            manufacturer="Dreo",
            model=self.device.model
        )

    @property
    def available(self) -> bool:
        """Return True if device is available."""
        # return self.device.connection_status == "online"
        return True

    @property
    def should_poll(self):
        return False

    def async_added_to_hass(self):
        """Register callbacks."""

        def update_state():
            # Tell HA we're ready to update
            self.schedule_update_ha_state(True)

        self.device.add_attr_callback(update_state)

Hi guys, I noticed that when you restart the server or Home Assistant, the Dreo entities may show up as unavailable. You can easily solve this by briefly switching the respective fans on or off in the Dreo app. The entities will then be available again in Home Assistant as normal until the next restart.

Home Assistant Supervised Installed (x64) Version 2024.5.2 Works in: βœ… Home Assistant Main βœ… Node Red βœ… HomeKit (Own Node)

JeffSteinbok commented 1 month ago

Thanks folks. I'll have a look this weekend. Sorry, been busy at work.

JeffSteinbok commented 1 month ago

@VOSsec Any chance you could push a PR with your change? I can verify it and make a release.

VOSsec commented 1 month ago

Good Morning (πŸ‡©πŸ‡ͺ) @JeffSteinbok, I tried to open a PR but got the following error "Pull request creation failed. Validation failed: must be a collaborator"

RoYoMi commented 1 month ago

@VOSsec excellent! That solves a problem I've been having with creating conditional tests for entity state. Thank you digging into this.

JeffSteinbok commented 1 month ago

I think you have to fork the repo and then submit the pull request

-Jeff

On May 7, 2024, at 9:27β€―PM, Tobias M. @.***> wrote:

ο»Ώ

Good Morning (πŸ‡©πŸ‡ͺ) @JeffSteinbokhttps://github.com/JeffSteinbok, I tried to open a PR but got the following error "Pull request creation failed. Validation failed: must be a collaborator"

β€” Reply to this email directly, view it on GitHubhttps://github.com/JeffSteinbok/hass-dreo/issues/87#issuecomment-2099716518, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABX5XT3AOH7MDWLC7V5M4PTZBGSRNAVCNFSM6AAAAABHDOCWH2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJZG4YTMNJRHA. You are receiving this because you were mentioned.Message ID: @.***>

JeffSteinbok commented 1 month ago

Let me see what I can do real quick.

JeffSteinbok commented 1 month ago

Ok, so your fix doesn't quite work. When things load up, they aren't updated. I have to go see what's going on here before I publish this.

JeffSteinbok commented 1 month ago

Fixed in version 0.6.4