Problems with custom integration Warema WMS Control after update 2025.1

After updating to 2025.1 I unfortunately have a problem with the custom integration for my WAREMA blinds.

Despite updating I haven’t changed anything but the entities are no logger working.

‘Check configuration’ is showing me the following:

Configuration warnings
Platform error 'cover' from integration 'warema_wms_webcontrol' - cannot import name 'DEVICE_CLASS_SHADE' from 'homeassistant.components.cover' (/usr/src/homeassistant/homeassistant/components/cover/__init__.py)

And I have the following log entry:

Logger: homeassistant.config
Source: config.py:1055
First occurred: January 7, 2025 at 14:43:54 (1 occurrences)
Last logged: January 7, 2025 at 14:43:54

Platform error: cover - cannot import name 'DEVICE_CLASS_SHADE' from 'homeassistant.components.cover' (/usr/src/homeassistant/homeassistant/components/cover/__init__.py)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config.py", line 1055, in _async_load_and_validate_platform_integration
    platform = await p_integration.integration.async_get_platform(domain)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1108, in async_get_platform
    platforms = await self.async_get_platforms((platform_name,))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1185, in async_get_platforms
    import_future.result()
    ~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1173, in async_get_platforms
    platforms.update(self._load_platforms(platform_names))
                     ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1098, in _load_platforms
    platform_name: self._load_platform(platform_name)
                   ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1272, in _load_platform
    cache[full_name] = self._import_platform(platform_name)
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1304, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/util/loop.py", line 200, in protected_loop_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.13/importlib/__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/config/custom_components/warema_wms_webcontrol/cover.py", line 7, in <module>
    from homeassistant.components.cover import (
        CoverEntity, DEVICE_CLASS_SHADE, SUPPORT_OPEN, SUPPORT_CLOSE,
        SUPPORT_SET_POSITION, ATTR_POSITION, PLATFORM_SCHEMA)
ImportError: cannot import name 'DEVICE_CLASS_SHADE' from 'homeassistant.components.cover' (/usr/src/homeassistant/homeassistant/components/cover/__init__.py)

I appreciate any help as it sucks to not be able to use the blinds via HA anymore. Updating to 2025.1.1 didn’t help.

Hello RodgerDodger,

That looks like something the Custom Integrator would need to fix.

Did you see if there is an issue open there or open one if it isn’t kn their GitHub?

I have created error with 2025.1: cannot import name 'DEVICE_CLASS_SHADE' · Issue #3 · cornim/ha-warema-integration · GitHub but I am not really hopeful that anything will come of it, judging from the activity on the repository.

Thank you, buddy, as pretty busy right now it’s very welcome.

Have you tried to readd the code files?

Fixed it with ChatGPT!

Will write more in afternoon/evening.

:tada: Works again!

Okay, I have thrown the full code of the /config/custom_components/warema_wms_webcontrol/cover.py into ChatGPT and got this as the result with the prompt “repair this code” (in German).

import logging
from datetime import datetime, timedelta

import voluptuous as vol

import homeassistant.helpers.config_validation as cv
from homeassistant.components.cover import (
    CoverEntity, CoverDeviceClass, CoverEntityFeature, ATTR_POSITION, PLATFORM_SCHEMA)

_LOGGER = logging.getLogger(__name__)

#TODO Should be moved to homeassistant.const
CONF_WEBCONTROL_SERVER_ADDR = 'webcontrol_server_addr'
CONF_UPDATE_INTERVAL = 'update_interval'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Optional(CONF_WEBCONTROL_SERVER_ADDR, default='http://webcontrol.local'): cv.url,
    vol.Optional(CONF_UPDATE_INTERVAL, default=600): cv.positive_int
})

def setup_platform(hass, config, add_devices, discovery_info=None):
    from warema_wms import Shade, WmsController
    shades = Shade.get_all_shades(WmsController(config[CONF_WEBCONTROL_SERVER_ADDR]), time_between_cmds=0.5)
    add_devices(WaremaShade(s, config[CONF_UPDATE_INTERVAL]) for s in shades)

class WaremaShade(CoverEntity):
    """Represents a warema shade"""

    def __init__(self, shade, update_interval: int):
        self.shade = shade
        self.room = shade.get_room_name()
        self.channel = shade.get_channel_name()
        self.position = 0
        self.last_position = self.position
        self.is_moving = False
        self.state_last_updated = datetime.now()
        self.next_state_update = datetime.now()
        '''This is needed because, when a move is triggered by HA, sometimes the next status update
        still reports 'not moving' because shitty warema hasn't caught up with reality yet
        and then the next update is delayed until for update_interval seconds'''
        self.force_update_until = datetime.now()
        self.update_interval = update_interval

    def update(self, force=False):
        if datetime.now() > self.next_state_update or self.is_moving \
                or datetime.now() < self.force_update_until or force:
            self.last_position = self.position
            self.position, self.is_moving, self.state_last_updated = \
                self.shade.get_shade_state(True)
            if self.state_last_updated:
                self.next_state_update = \
                    self.state_last_updated \
                    + timedelta(seconds=self.update_interval)
            _LOGGER.debug('Update performed for {}'.format(self.name))
        else:
            _LOGGER.debug('Update skipped for {}. Next update {}'
                          .format(self.name, self.next_state_update))

    @property
    def device_class(self):
        return CoverDeviceClass.SHADE

    @property
    def supported_features(self):
        return CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE | CoverEntityFeature.SET_POSITION

    @property
    def unique_id(self):
        return 'warema_shade_{}'.format(self.name)

    @property
    def name(self):
        return "{}:{}".format(self.room, self.channel)

    @property
    def current_cover_position(self):
        return 100 - self.position

    @property
    def is_opening(self):
        return self.is_moving and self.last_position > self.position

    @property
    def is_closing(self):
        return self.is_moving and self.last_position < self.position

    @property
    def is_closed(self):
        return not self.is_moving and self.position == 100

    def open_cover(self, **kwargs):
        self.force_update_until = datetime.now() + timedelta(seconds=15)
        self.shade.set_shade_position(0)

    def close_cover(self, **kwargs):
        self.force_update_until = datetime.now() + timedelta(seconds=15)
        self.shade.set_shade_position(100)

    def set_cover_position(self, **kwargs):
        self.force_update_until = datetime.now() + timedelta(seconds=15)
        self.shade.set_shade_position(100 - kwargs[ATTR_POSITION])

I backed up my system and copied the ChatGPT code into /config/custom_components/warema_wms_webcontrol/cover.py, saved, checked the code via Developer Tools (with no error left) and restarted HA.

My 4 enttites - as I have for shades - were recreated as ‘_2’ and after deleting the old ones and renaming the new ones I’m good to go and everything works just like before!