rospogrigio / localtuya

local handling for Tuya devices
GNU General Public License v3.0
2.75k stars 533 forks source link

Error with 'SPEED_HIGH' #780

Open Seidel76 opened 2 years ago

Seidel76 commented 2 years ago

Hello, i upgraded the Core of Hassio, and i've this error:

2022-03-31 07:50:15 ERROR (MainThread) [homeassistant.setup] Setup failed for custom integration localtuya: Unable to import component: cannot import name 'SPEED_HIGH' from 'homeassistant.components.fan' (/usr/src/homeassistant/homeassistant/components/fan/__init__.py)

What can I do for resolve it ?

YDeltagon commented 2 years ago

Same here : Logger: homeassistant.setup Source: setup.py:162 First occurred: 15:35:19 (1 occurrences) Last logged: 15:35:19

Setup failed for custom integration localtuya: Unable to import component: cannot import name 'SPEED_HIGH' from 'homeassistant.components.fan' (/usr/src/homeassistant/homeassistant/components/fan/init.py)

Fresh install of HomeAssistant (os) and HACS ;)

CloCkWeRX commented 2 years ago

Relevant code: https://github.com/rospogrigio/localtuya/blob/d783293a213c07e7b3cf99b7c2a1d222602cc3ae/custom_components/localtuya/fan.py#L7

These constants were removed in https://github.com/home-assistant/core/commit/7fbe1dbc99b7cdf503820d2d0356090766ae1f7e https://github.com/home-assistant/core/pull/59781

What we want to do here is refactor the presets to be based around a percentage model.

Before that breaking change, these were mapped like:

    def speed_to_percentage(self, speed: str) -> int:
        """
        Map a speed to a percentage.
        Officially this should only have to deal with the 4 pre-defined speeds:
        return {
            SPEED_OFF: 0,
            SPEED_LOW: 33,
            SPEED_MEDIUM: 66,
            SPEED_HIGH: 100,
        }[speed]
        Unfortunately lots of fans make up their own speeds. So the default
        mapping is more dynamic.
        """

From the looks of it, we are best off refactoring the updates to state:

    def status_updated(self):
        """Get state of Tuya fan."""
        self._is_on = self._status["dps"]["1"]
        if not self._status["dps"]["1"]:
            self._speed = SPEED_OFF # Change to self._percentage = 0
        elif self._status["dps"]["2"] == "1":
            self._speed = SPEED_LOW # Change to self._percentage = 33
        elif self._status["dps"]["2"] == "2":
            self._speed = SPEED_MEDIUM # Change to self._percentage = 66
        elif self._status["dps"]["2"] == "3":
            self._speed = SPEED_HIGH # Change to self._percentage = 100
        self._oscillating = self._status["dps"]["8"]

and this method gets replaced by async_set_percentage; plus some between 0 and 32, 33 and 65, 66 and 100, 100 checks.

    async def async_set_speed(self, speed: str) -> None:
        """Set the speed of the fan."""
        if speed == SPEED_OFF:
            await self._device.set_dp(False, "1")
        elif speed == SPEED_LOW:
            await self._device.set_dp("1", "2")
        elif speed == SPEED_MEDIUM:
            await self._device.set_dp("2", "2")
        elif speed == SPEED_HIGH:
            await self._device.set_dp("3", "2")
        self.schedule_update_ha_state()

I'm happy to draft a PR to that effect, but dont own any actual fans I can test this with.

CloCkWeRX commented 2 years ago

This is already fixed in https://github.com/rospogrigio/localtuya/pull/542

I would recommend you update or try running from the master branch.

CloCkWeRX commented 2 years ago

Fixed, released in 3.5.0 - this is closable.