homeassistant-midea-dehumidifier icon indicating copy to clipboard operation
homeassistant-midea-dehumidifier copied to clipboard

Entity not recognized since update.

Open Krushx0 opened this issue 1 year ago • 4 comments

I have two errors in the logs:

Error 1:

Logger: homeassistant.setup Source: setup.py:403 First occurred: 14:49:28 (2 occurrences) Last logged: 14:49:29

Unable to prepare setup for platform 'midea_dehumidifier.sensor': Platform not found (Exception importing custom_components.midea_dehumidifier.sensor). Unable to prepare setup for platform 'midea_dehumidifier.humidifier': Platform not found (Exception importing custom_components.midea_dehumidifier.humidifier).

Error 2:

Logger: homeassistant.loader Source: loader.py:842 First occurred: 14:49:28 (2 occurrences) Last logged: 14:49:29

Unexpected exception importing platform custom_components.midea_dehumidifier.sensor Unexpected exception importing platform custom_components.midea_dehumidifier.humidifier Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/loader.py", line 842, in get_platform cache[full_name] = self._import_platform(platform_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/loader.py", line 859, in _import_platform return importlib.import_module(f"{self.pkg_path}.{platform_name}") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1204, in _gcd_import File "", line 1176, in _find_and_load File "", line 1147, in _find_and_load_unlocked File "", line 690, in _load_unlocked File "", line 936, in exec_module File "", line 1074, in get_code File "", line 1004, in source_to_code File "", line 241, in _call_with_frames_removed File "/config/custom_components/midea_dehumidifier/sensor.py", line 54 self._device_class = SensorDeviceClass.HUMIDITY ^ TabError: inconsistent use of tabs and spaces in indentation

Krushx0 avatar Jan 22 '24 13:01 Krushx0

i also have the same errors

JimRnewell avatar Jan 26 '24 11:01 JimRnewell

Hello, unfortunately I have the same error! it can't find the dehumidifier!

` Logger: homeassistant.setup Source: setup.py:403 First occurred: 6:55:46 PM (2 occurrences) Last logged: 6:55:46 PM

Unable to prepare setup for platform 'midea_dehumidifier.humidifier': Platform not found (Exception importing custom_components.midea_dehumidifier.humidifier).
Unable to prepare setup for platform 'midea_dehumidifier.sensor': Platform not found (Exception importing custom_components.midea_dehumidifier.sensor).

`

`Logger: homeassistant.loader Source: loader.py:842 First occurred: 8:04:05 PM (2 occurrences) Last logged: 8:04:05 PM

Unexpected exception importing platform custom_components.midea_dehumidifier.humidifier Unexpected exception importing platform custom_components.midea_dehumidifier.sensor Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/loader.py", line 842, in get_platform cache[full_name] = self._import_platform(platform_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/loader.py", line 859, in _import_platform return importlib.import_module(f"{self.pkg_path}.{platform_name}") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1204, in _gcd_import File "", line 1176, in _find_and_load File "", line 1147, in _find_and_load_unlocked File "", line 690, in _load_unlocked File "", line 936, in exec_module File "", line 1074, in get_code File "", line 1004, in source_to_code File "", line 241, in _call_with_frames_removed File "/config/custom_components/midea_dehumidifier/humidifier.py", line 187 self._device_class = HumidifierDeviceClass.DEHUMIDIFIER ^ TabError: inconsistent use of tabs and spaces in indentation `

SkyTalker avatar Jan 31 '24 17:01 SkyTalker

After the update to version 1.0.4, the integration of my device stopped working. Apart from reverting to the previous version 1.0.3, which works correctly, I tried to keep 1.0.4 and identify the problem. The file:
/homeassistant/custom_components/midea_dehumidifier/humidifier.py Seems to have issues with the initialization of my device. I made some changes that, in my case, seem to work fine. Below is the modified code. Please note that after editing the file and restarting the server, it takes a few seconds for the device card to initialize and update.

humidifier.py

"""
Custom integation based on humidifer and sensor platforms for EVA II PRO WiFi Smart Dehumidifier appliance by Midea/Inventor.
For more details please refer to the documentation at
https://github.com/barban-dev/midea_inventor_dehumidifier
Modifiche apportate da Enrico:

1. Metodo identificazione dispositivo come versione precedente.
   [Identifying the device as a previous version.]

2. Aggiunta di messaggi di errore nella sincronizzazione del dispositivo.
   [Added error messages during device synchronization.]

3. Rimozione di commenti ed alcune parti di codice duplicato.
   [Removed comments and some duplicated code sections.]
"""
VERSION = '1.0.4'

import logging
from typing import List, Optional
from custom_components.midea_dehumidifier import DOMAIN, MIDEA_API_CLIENT, MIDEA_TARGET_DEVICE
from homeassistant.const import ATTR_MODE

from homeassistant.components.humidifier import HumidifierEntity, HumidifierDeviceClass, HumidifierEntityFeature
from homeassistant.components.humidifier.const import (
    ATTR_AVAILABLE_MODES,
    ATTR_HUMIDITY,
    ATTR_MAX_HUMIDITY,
    ATTR_MIN_HUMIDITY,
    DEFAULT_MAX_HUMIDITY,
    DEFAULT_MIN_HUMIDITY,
    SERVICE_SET_HUMIDITY,
    SERVICE_SET_MODE
)

import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import service
from homeassistant.helpers.dispatcher import async_dispatcher_connect, async_dispatcher_send
from homeassistant.core import callback

# Constants
ATTR_ENTITY_ID = "entity_id"

SERVICE_SET_FAN_SPEED = "set_fan_speed"
ATTR_FAN_SPEED = "fan_speed"
SERVICE_SET_ION_STATE = "set_ion_state"
ATTR_ION_STATE = "ion_state"
SERVICE_SET_MODE = "set_mode"
ATTR_MODE = "mode"
_LOGGER = logging.getLogger(__name__)

# More constants
SUPPORT_FLAGS = HumidifierEntityFeature.MODES

MIN_HUMIDITY = 35
MAX_HUMIDITY = 70

DEHUMI_MODES_DICT = {'TARGET_HUMIDITY': 1, 'CONTINUOUS': 2, 'SMART': 3, 'DRYER': 4}
DEHUMI_MODES_LIST = ['Target_humidity', 'Continuous', 'Smart', 'Dryer']

DEHUMI_FAN_SPEED_DICT = {'SILENT': 40, 'MEDIUM': 60, 'HIGH': 80}
DEHUMI_FAN_SPEED_LIST = ['Silent', 'Medium', 'High']

ATTR_ION_SET_SWITCH = "ion"
ATTR_FAN_SPEED_MODE = "fan_speed_mode"
ATTR_CURRRENT_HUMIDITY = "current_humidity"
ATTR_TANK = "tank_show"
PROP_TO_ATTR = {
    "ionSetSwitch": ATTR_ION_SET_SWITCH,
    "mode": ATTR_MODE,
    "windSpeedMode": ATTR_FAN_SPEED_MODE,
    "windSpeed": ATTR_FAN_SPEED,
    "current_humidity": ATTR_CURRRENT_HUMIDITY,
    "tank_show": ATTR_TANK,
}

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    _LOGGER.info("midea_dehumidifier: initializing the dehumidifier platform")
    _LOGGER.debug("midea_dehumidifier: starting async_setup_platform")
    _LOGGER.debug("midea_dehumidifier: MIDEA_API_CLIENT=" + MIDEA_API_CLIENT)
    _LOGGER.debug("midea_dehumidifier: MIDEA_TARGET_DEVICE=" + MIDEA_TARGET_DEVICE)
    client = hass.data[MIDEA_API_CLIENT]
    targetDevice = discovery_info[MIDEA_TARGET_DEVICE]
    _LOGGER.debug("midea_dehumidifier: targetDevice = %s", targetDevice)

    if targetDevice is not None:
        async_add_entities([MideaDehumidifierDevice(hass, client, targetDevice)])
        _LOGGER.info("midea_dehumidifier: dehumidifier entity initialized.")
    else:
        _LOGGER.error("midea_dehumidifier: error during dehumidifier entity initialization.")

    async def async_service_set_fan_speed(call):
        entity_id = call.data[ATTR_ENTITY_ID]
        speed_mode = call.data[ATTR_FAN_SPEED]
        async_dispatcher_send(hass, SERVICE_SET_FAN_SPEED.format(entity_id), speed_mode)
        
    return True
    
async def async_setup_entry(hass, config_entry, async_add_entities):
    await async_setup_platform(hass, {}, async_add_entities)

async def async_update(self):
    if self._client.security.access_token:
        res = await self.hass.async_add_executor_job(self._client.get_device_status, self._device['id'])
        if res is not None:
            self.__refresh_device_status()
        else:
            _LOGGER.error("midea-dehumidifier: get_device_status returned None.")
    else:
        _LOGGER.error("midea-dehumidifier: Access token is not available.")

class MideaDehumidifierDevice(HumidifierEntity):
    def __init__(self, hass, client, targetDevice):
        self._hass = hass
        self._supported_features = SUPPORT_FLAGS
        self._fan_dict = DEHUMI_FAN_SPEED_DICT
        self._fan_list = DEHUMI_FAN_SPEED_LIST
        self._modes_dict = DEHUMI_MODES_DICT
        self._available_modes = DEHUMI_MODES_LIST
        self._client = client
        self._device = targetDevice
        self._name = "midea_dehumidifier_"+targetDevice['id']
        self._unique_id = 'midea_dehumidifier_' + targetDevice['id']
        self._device_class = HumidifierDeviceClass.DEHUMIDIFIER
        self._powerMode = None
        self._mode = None
        self._ionSetSwitch = None
        self._humidity = None
        self._humidity_set = None
        self._humidity_dot = None
        self._humidity_dot_set = None
        self._windSpeed = None
        self._windSpeedMode = None
        self._isDisplay = None
        self._filterShow = False
        self._tankShow = False
        self._dryClothesSetSwitch = None
        self._upanddownSwing = None

    @property
    def unique_id(self):
        return self._unique_id

    @property
    def name(self):
        return self._name

    @property
    def supported_features(self):
        return self._supported_features

    @property
    def should_poll(self):
        return True

    @property
    def target_humidity(self):
        return self._humidity_set

    @property
    def mode(self):
        return self._mode

    @property
    def available_modes(self):
        return self._available_modes

    @property
    def is_on(self):
        return self._powerMode

    @property
    def device_class(self):
        return self._device_class

    @property
    def ionSetSwitch(self):
        return self._ionSetSwitch

    @property
    def windSpeed(self):
        return self._windSpeed

    @property
    def windSpeedMode(self):
        return self._windSpeedMode

    @property
    def current_humidity(self):
        return self._humidity

    @property
    def min_humidity(self):
        return 40

    @property
    def max_humidity(self):
        return 85

    @property
    def tank_show(self):
        return self._tankShow

    @property
    def device_state_attributes(self):
        data = {}
        for prop, attr in PROP_TO_ATTR.items():
            value = getattr(self, prop)
            if value is not None:
                data[attr] = value
        return data

    def __refresh_device_status(self):
        if self._client.deviceStatus is not None:
            self._powerMode = self._client.deviceStatus.powerMode
            self._ionSetSwitch = self._client.deviceStatus.ionSetSwitch
            self._mode = self._available_modes[self._client.deviceStatus.setMode - 1]
            self._windSpeed = self._client.deviceStatus.windSpeed
            if self._windSpeed == 40:
                self._windSpeedMode = self._fan_list[0]
            elif self._windSpeed == 60:
                self._windSpeedMode = self._fan_list[1]
            elif self._windSpeed == 80:
                self._windSpeedMode = self._fan_list[2]
            else:
                self._windSpeedMode = "unknown"
            self._humidity = self._client.deviceStatus.humidity
            self._humidity_set = self._client.deviceStatus.humidity_set
            self._humidity_dot = self._client.deviceStatus.humidity_dot
            self._humidity_dot_set = self._client.deviceStatus.humidity_dot_set
            self._isDisplay = self._client.deviceStatus.isDisplay
            self._filterShow = self._client.deviceStatus.filterShow
            self._tankShow = self._client.deviceStatus.tankShow
            self._dryClothesSetSwitch = self._client.deviceStatus.dryClothesSetSwitch
            self._upAndDownSwing = self._client.deviceStatus.upAndDownSwing

    async def async_update(self):
        if self._client.security.access_token:
            res = await self.hass.async_add_executor_job(self._client.get_device_status, self._device['id'])
            if res is not None:
                self.__refresh_device_status()
            else:
                _LOGGER.error("midea-dehumidifier: get_device_status returned None.")
        else:
            _LOGGER.error("midea-dehumidifier: Access token is not available.")

    async def async_turn_on(self, **kwargs):
        if not self.is_on:
            res = await self.hass.async_add_executor_job(self._client.send_poweron_command, self._device["id"])
            if res is not None:
                self.__refresh_device_status()
            else:
                _LOGGER.error("midea-dehumidifier: send_poweron_command ERROR.")

    async def async_turn_off(self, **kwargs):
        if self.is_on:
            res = await self.hass.async_add_executor_job(self._client.send_poweroff_command, self._device["id"])
            if res is not None:
                self.__refresh_device_status()
            else:
                _LOGGER.error("midea-dehumidifier: send_poweroff_command ERROR.")

    async def async_set_humidity(self, humidity):
        if self.is_on:
            if self._humidity_set != humidity:
                res = await self.hass.async_add_executor_job(self._client.send_target_humidity_command, self._device["id"], humidity)
                if res is not None:
                    self.__refresh_device_status()
                else:
                    _LOGGER.error("midea-dehumidifier: send_target_humidity_command ERROR")

    async def async_set_mode(self, mode):
        if self.is_on:
            mode_num = self._modes_dict.get(mode.upper(), 0)
            res = await self.hass.async_add_executor_job(self._client.send_mode_command, self._device["id"], mode_num)
            if res is not None:
                self._client.deviceStatus._setMode = mode_num
                self.__refresh_device_status()
            else:
                _LOGGER.error("midea-dehumidifier: send_mode_command ERROR.")

    async def async_added_to_hass(self):
        async_dispatcher_connect(self.hass, SERVICE_SET_FAN_SPEED.format(self.entity_id), self.service_set_fan_speed)
        async_dispatcher_connect(self.hass, SERVICE_SET_ION_STATE.format(self.entity_id), self.service_set_ion_state)
        async_dispatcher_connect(self.hass, SERVICE_SET_MODE.format(self.entity_id), self.service_set_mode)

    @callback
    async def service_set_fan_speed(self, speed_mode):
        speed = self._fan_dict.get(speed_mode.upper(), 0)
        if self.is_on and self._windSpeed != speed and self._client.deviceStatus.setMode != 4:
            res = await self.hass.async_add_executor_job(self._client.send_fan_speed_command, self._device["id"], speed)
            if res is not None:
                self._windSpeed = speed
                self._windSpeedMode = speed_mode
                state = self._hass.states.get('humidifier.' + self._unique_id)
                if state:
                    attrs = state.attributes.copy()
                    attrs[ATTR_FAN_SPEED_MODE] = speed_mode
                    attrs[ATTR_FAN_SPEED] = speed
                    self._hass.states.async_set('humidifier.' + self._unique_id, state.state, attrs, force_update=True)
            else:
                _LOGGER.error("midea-dehumidifier: send_fan_speed_command ERROR.")

    @callback
    async def service_set_ion_state(self, ion_state):
        if self.is_on and self._ionSetSwitch != ion_state:
            if ion_state:
                res = await self.hass.async_add_executor_job(self._client.send_ion_on_command, self._device["id"])
            else:
                res = await self.hass.async_add_executor_job(self._client.send_ion_off_command, self._device["id"])
            if res is not None:
                self._ionSetSwitch = ion_state
                state = self._hass.states.get('humidifier.' + self._unique_id)
                if state:
                    attrs = state.attributes.copy()
                    attrs[ATTR_ION_SET_SWITCH] = ion_state
                    self._hass.states.async_set('humidifier.' + self._unique_id, state.state, attrs, force_update=True)
            else:
                _LOGGER.error("midea-dehumidifier: send_ion_(on/off)_command ERROR.")

    @callback
    async def service_set_mode(self, mode_name):
        mode = self._modes_dict.get(mode_name.upper(), 0)
        if self.is_on and self._mode != mode:
            res = await self.hass.async_add_executor_job(self._client.send_mode_command, self._device["id"], mode)
            if res is not None:
                self._mode = mode_name
                if mode == 4:
                    self._windSpeedMode = 'High'
                    self._windSpeed = self._fan_dict.get('HIGH', 0)
                state = self._hass.states.get('humidifier.' + self._unique_id)
                if state:
                    attrs = state.attributes.copy()
                    attrs[ATTR_MODE] = mode_name
                    if mode == 4:
                        attrs[ATTR_FAN_SPEED_MODE] = 'High'
                        attrs[ATTR_FAN_SPEED] = self._fan_dict.get('HIGH', 0)
                    self._hass.states.async_set('humidifier.' + self._unique_id, state.state, attrs, force_update=True)
            else:
                _LOGGER.error("midea-dehumidifier: send_mode_command ERROR.")

enricota66 avatar Jan 31 '24 20:01 enricota66

Still facing same error with 2024.4.4:

Logger: homeassistant.loader Quelle: loader.py:1232 Erstmals aufgetreten: 22:14:58 (2 Vorkommnisse) Zuletzt protokolliert: 22:14:59

Unexpected exception importing platform custom_components.midea_dehumidifier.sensor Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/loader.py", line 1232, in _load_platform cache[full_name] = self._import_platform(platform_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/loader.py", line 1264, in _import_platform return importlib.import_module(f"{self.pkg_path}.{platform_name}") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/importlib/init.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1387, in _gcd_import File "", line 1360, in _find_and_load File "", line 1331, in _find_and_load_unlocked File "", line 935, in _load_unlocked File "", line 991, in exec_module File "", line 1129, in get_code File "", line 1059, in source_to_code File "", line 488, in _call_with_frames_removed File "/config/custom_components/midea_dehumidifier/sensor.py", line 54 self._device_class = SensorDeviceClass.HUMIDITY ^ TabError: inconsistent use of tabs and spaces in indentation

hstar42 avatar Apr 29 '24 20:04 hstar42

Still facing same error with 2024.4.4:

Logger: homeassistant.loader Quelle: loader.py:1232 Erstmals aufgetreten: 22:14:58 (2 Vorkommnisse) Zuletzt protokolliert: 22:14:59

Unexpected exception importing platform custom_components.midea_dehumidifier.sensor Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/loader.py", line 1232, in _load_platform cache[full_name] = self._import_platform(platform_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/loader.py", line 1264, in _import_platform return importlib.import_module(f"{self.pkg_path}.{platform_name}") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/importlib/init.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1387, in _gcd_import File "", line 1360, in _find_and_load File "", line 1331, in _find_and_load_unlocked File "", line 935, in _load_unlocked File "", line 991, in exec_module File "", line 1129, in get_code File "", line 1059, in source_to_code File "", line 488, in _call_with_frames_removed File "/config/custom_components/midea_dehumidifier/sensor.py", line 54 self._device_class = SensorDeviceClass.HUMIDITY ^ TabError: inconsistent use of tabs and spaces in indentation

I faced the same problem, but it's easy to fix. Just clear out the tab spaces on line 54 and replace them with spaces. I also encountered this issue in another line within humidifier.py, but the log will indicate the specific line. Basically, it involves the new lines added with "self._device_class = SensorDeviceClass.HUMIDITY". Using the script from @enricota66 cleared out the other bug with the missing platform, and I managed to get this integration working. Thanks!

RazoraDE avatar Jul 26 '24 19:07 RazoraDE