Midea_dehumi Custom Component (Midea/Inventor Invmate EVA II PRO WiFi dehumidifier)

I’m getting an warning in my home assistant logs. But the automation works.
I have a automation that automatically shut down the air purifier at a set level, but only when the condition of the dehumidifier is on and drop-down selection is Living Room.
So i geus this warning coming from these automation, and has to do where it reads the state of the dehumidifier.

But why? i don’t see a problem.

The Warning:

Log Details (WARNING)
Logger: homeassistant.helpers.condition
Source: helpers/condition.py:234
First occurred: 9:48:25 (1 occurrences)
Last logged: 9:48:25

Value cannot be processed as a number: <state humidifier.midea_dehumidifier_30786325603194=on; min_humidity=40, max_humidity=85, available_modes=['Target_humidity', 'Continuos', 'Smart', 'Dryer'], humidity=45, mode=Target_humidity, ion=0, fan_speed_mode=High, fan_speed=80, current_humidity=54, tank_show=False, friendly_name=midea_dehumidifier_30786325603194, supported_features=1, device_class=dehumidifier @ 2020-12-25T08:16:36.460056+01:00> (Offending entity: on)

The automation:

- id: 'xxxxxxxxxxx'
  alias: Dehumidifier - Living Room Off
  trigger:
  - platform: numeric_state
    entity_id: humidifier.midea_dehumidifier_30786325603194
    for: 00:05:00
    below: '50'
  - type: opened
    platform: device
    device_id: 662e22ee9cc6a3493c53cc8cd4765d57
    entity_id: binary_sensor.raamsensor_eetkamer_on_off
    domain: binary_sensor
    for:
      hours: 0
      minutes: 0
      seconds: 15
  condition:
  - condition: state
    entity_id: input_select.room
    state: Woonkamer
  - condition: state
    entity_id: sensor.midea_dehumidifier_30786325603194
    state: 'on'
  action:
  - service: humidifier.turn_off
    data: {}
    entity_id: humidifier.midea_dehumidifier_30786325603194
  mode: single

By the way it is not necessary to set the sensor in the template =true

This is the same
{{ states.humidifier.midea_dehumidifier_XXXXXXXXXXXXXX.attributes.tank_show}}

Whoever is looking for the same AC solution as I was, https://github.com/mac-zhou/midea-ac-py is working for me.

Does it work for Dehumidifier too?

I dont have a Dehumidifier but from what I read on the github link I dont think it will (see below).

Note: This component only supports devices with model 0xac (air conditioner).

If marc-zhou’s solution is working for this type of dehumidifier, then this one should work also, as Marc is the base for it all😉


(Which is a spin off for Midea-A/C, thanks also to Rene Klootwijk and Sergey Dudanov)

Hi,
I’m trying to configure cards as yours, but can’t find what type to use to display drop down menù to set modes without tap on the dehumidifier card.
Can you help me?

The drop down is just the entities card :slight_smile:

So what’s wrong with my entities card? :frowning:
image

Nothing is wrong. That’s the entity for the dehumidifier. The dropdowns are for the input_select entities

You saved my life :rofl:
As them are not shown if you search for “midea” I’ve never seen them!
Thank you very much.

source code updated.
Thanks

1 Like

Hi @barban,
Just dl and i try to install now ;-))

I wonder if the update it include a solution for house with multiple deshumidifier ?
I am in that case with @HVPereira (post 74 & 75 Dec20)

Actually, as per my understanding someone implemented a better solution for the multiple devices.

Credits to gianluca.

in init .py, I pushed into hass.data new client for each appliace:

    if not deviceId:
        if appliances is not None:
            for a in appliances:
                if a["type"] == "0xA1":
                    deviceId = str(a["id"])
                    targetDevice = a
                    client_for_device = MideaClient(username, password, sha256password, cacheTimeInSeconds = 0)
                    res = await hass.async_add_executor_job(client_for_device.login)
                    if res != -1:
                        sessionId = client_for_device.current["sessionId"]
                        _LOGGER.info("midea-dehumi: login success, sessionId=%s", sessionId)
                        hass.data[MIDEA_API_CLIENT + "_" + a["id"]] = client_for_device
                    _LOGGER.info("midea-dehumidifier: loading humidifier entity sub-component...")
                    load_platform(hass, 'humidifier', DOMAIN, {MIDEA_TARGET_DEVICE: targetDevice}, config)
                    _LOGGER.info("midea-dehumidifier: loading sensor entity sub-component...")
                    load_platform(hass, 'sensor', DOMAIN, {MIDEA_TARGET_DEVICE: targetDevice}, config)
                    _LOGGER.info("midea_dehumidifier: platform successfuly initialized.")
    else:
        if appliances is not None:
            for a in appliances:
                if a["type"] == "0xA1" and deviceId == str(a["id"]):
                    targetDevice = a

the key is: hass.data[MIDEA_API_CLIENT + "_" + a["id"]] = client_for_device

In humidifier.py, I changed the way to get client:

self._client = hass.data[MIDEA_API_CLIENT + "_" + targetDevice['id']]

Hope it helps

I belive this is a much better solution I haven’t tested it myself but will try it this weekend.

Best Regards,
HP

Hello again,

For those of you who are trying to have several devices with different humidity sensors. Please find my init.py and humidifier,py in attachment.

All the credits should go to gianluca and barban of course as they were the ones who managed to get here :slight_smile:

I’m very happy to share these files, Hope you find it as useful as I did.

init.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
"""
VERSION = '1.0.0'

DOMAIN = "midea_dehumidifier"
MIDEA_API_CLIENT = "midea_api_client"
MIDEA_TARGET_DEVICE = "midea_target_device"


import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import load_platform
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD

import asyncio
from homeassistant.config_entries import ConfigEntry

_LOGGER = logging.getLogger(__name__)

CONF_SHA256_PASSWORD = 'sha256password'
CONF_DEVICEID = 'deviceId'

CONFIG_SCHEMA = vol.Schema({
    DOMAIN: vol.Schema({
        vol.Required(CONF_USERNAME): cv.string,
        vol.Optional(CONF_PASSWORD): cv.string,
        vol.Optional(CONF_SHA256_PASSWORD): cv.string,
        vol.Optional(CONF_DEVICEID): cv.string
    })
}, extra=vol.ALLOW_EXTRA)


async def async_setup(hass, config):
    """Set up client for Midea API based on configuration entries."""
    _LOGGER.info("midea_dehumidifier: initializing platform...")
    _LOGGER.debug("midea_dehumidifier: starting async_setup")

    if DOMAIN not in config:
        _LOGGER.error("midea_dehumi: cannot find midea_dehumi platform on configuration.yaml")
        return False

    from midea_inventor_lib import MideaClient
    	
    username = config[DOMAIN].get(CONF_USERNAME)
    password = config[DOMAIN].get(CONF_PASSWORD)
    sha256password = config[DOMAIN].get(CONF_SHA256_PASSWORD)
    deviceId = config[DOMAIN].get(CONF_DEVICEID)
	
    #_LOGGER.debug("midea_dehumi: CONFIG PARAMS: username=%s, password=%s, sha256password=%s, deviceId=%s", username, password, sha256password, deviceId)

    if not password and not sha256password:
        _LOGGER.error("midea_dehumi: either plain-text password or password's sha256 hash should be specified in config entries.")
        return False

    #Create client
    client = MideaClient(username, password, sha256password, cacheTimeInSeconds = 0)

    #Log-in to the Midea cloud Web Service and get the list of configured Midea/Inventor appliances for the user.
    _LOGGER.info("midea_dehumi: logging into Midea API Web Service...")

    #res = client.login()
    res = await hass.async_add_executor_job(client.login)
    if res == -1:
        _LOGGER.error("midea-dehumi: login error")
        return False
    else:
        sessionId = client.current["sessionId"]
        _LOGGER.info("midea-dehumi: login success, sessionId=%s", sessionId)

    appliances = {}

    #appliances = client.listAppliances()
    appliances = await hass.async_add_executor_job(client.listAppliances)
    
    appliancesStr = ""
    for a in appliances:
        appliancesStr = "[id="+a["id"]+" type="+a["type"]+" name="+a["name"]+"]"
    if a["onlineStatus"] == "1":
        appliancesStr += " is online,"
    else:
        appliancesStr += " is offline,"
    if a["activeStatus"] == "1":
        appliancesStr += " is active.\n"
    else:
        appliancesStr += " is not active.\n"
		
    _LOGGER.info("midea-dehumi: "+appliancesStr)
    
    #The first appliance having type="0xA1" is returned for default (TODO: otherwise, 'deviceId' configuration option can be used)
    hass.data[MIDEA_API_CLIENT] = client
    targetDevice = None
    if not deviceId:
        if appliances is not None:
            for a in appliances:
                if a["type"] == "0xA1":
                    deviceId = str(a["id"])
                    targetDevice = a
                    client_for_device = MideaClient(username, password, sha256password, cacheTimeInSeconds = 0)
                    res = await hass.async_add_executor_job(client_for_device.login)
                    if res != -1:
                        sessionId = client_for_device.current["sessionId"]
                        _LOGGER.info("midea-dehumi: login success, sessionId=%s", sessionId)
                        hass.data[MIDEA_API_CLIENT + "_" + a["id"]] = client_for_device
                    _LOGGER.info("midea-dehumidifier: loading humidifier entity sub-component...")
                    load_platform(hass, 'humidifier', DOMAIN, {MIDEA_TARGET_DEVICE: targetDevice}, config)
                    _LOGGER.info("midea-dehumidifier: loading sensor entity sub-component...")
                    load_platform(hass, 'sensor', DOMAIN, {MIDEA_TARGET_DEVICE: targetDevice}, config)
                    _LOGGER.info("midea_dehumidifier: platform successfuly initialized.")
    else:
        if appliances is not None:
            for a in appliances:
                if a["type"] == "0xA1" and deviceId == str(a["id"]):
                    targetDevice = a


    if targetDevice:
 #       _LOGGER.info("midea-dehumidifier: device type 0xA1 found.")

#        hass.data[MIDEA_API_CLIENT] = client
#        _LOGGER.info("midea-dehumidifier: loading humidifier entity sub-component...")
#        load_platform(hass, 'humidifier', DOMAIN, {MIDEA_TARGET_DEVICE: targetDevice}, config)

#        _LOGGER.info("midea-dehumidifier: loading sensor entity sub-component...")
#        load_platform(hass, 'sensor', DOMAIN, {MIDEA_TARGET_DEVICE: targetDevice}, config)

#        _LOGGER.info("midea_dehumidifier: platform successfuly initialized.")
        return True
    else:
        _LOGGER.error("midea-dehumidifier: device type 0xA1 not found.")
        return False

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
"""
VERSION = '1.0.1'

import logging
from midea_inventor_lib import MideaClient
from typing import List, Optional
from custom_components.midea_dehumidifier import DOMAIN, MIDEA_API_CLIENT, MIDEA_TARGET_DEVICE

from homeassistant.components.humidifier import HumidifierEntity
from homeassistant.components.humidifier.const import (
    ATTR_AVAILABLE_MODES,
    ATTR_HUMIDITY,
    ATTR_MAX_HUMIDITY,
    ATTR_MIN_HUMIDITY,
    ATTR_MODE,
    DEFAULT_MAX_HUMIDITY,
    DEFAULT_MIN_HUMIDITY,
    DEVICE_CLASS_DEHUMIDIFIER,
    SERVICE_SET_HUMIDITY,
    SERVICE_SET_MODE,
    SUPPORT_MODES
)

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


ATTR_ENTITY_ID = "entity_id"

SERVICE_SET_FAN_SPEED = "set_fan_speed"
ATTR_FAN_SPEED = "fan_speed"
SERVICE_SET_FAN_SPEED_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_id,
    vol.Required(ATTR_FAN_SPEED): cv.string,
})

SERVICE_SET_ION_STATE = "set_ion_state"
ATTR_ION_STATE = "ion_state"
SERVICE_SET_ION_STATE_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_id,
    vol.Required(ATTR_ION_STATE): cv.boolean,
})

SERVICE_SET_MODE = "set_mode"
ATTR_MODE = "mode"
SERVICE_SET_MODE_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_id,
    vol.Required(ATTR_MODE): cv.string,
})


_LOGGER = logging.getLogger(__name__)

#SUPPORT_FLAGS = 0
SUPPORT_FLAGS = SUPPORT_MODES

#TODO: in midea_dehumi python lib the range 30-70 is hard coded (fix it)
MIN_HUMITIDY = 35
MAX_HUMITIDY = 70

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

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


#States Attributes
ATTR_ION_SET_SWITCH = "ion"
#ATTR_MODE = "mode"
ATTR_FAN_SPEED_MODE = "fan_speed_mode"
#ATTR_FAN_SPEED = "fan_speed"
ATTR_CURRRENT_HUMIDITY = "current_humidity"
ATTR_TANK_SHOW = '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_SHOW,
}


async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    """Set up Midea/Inventor dehumidifier platform based on config_entry."""
    _LOGGER.info("midea_dehumidifier: initializing humidifier 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)

    #ref: https://developers.home-assistant.io/docs/en/creating_component_generic_discovery.html
    client = hass.data[MIDEA_API_CLIENT]
    targetDevice = discovery_info[MIDEA_TARGET_DEVICE]
    _LOGGER.debug("midea_dehumidifier: targetDevice = %s", targetDevice)

    if targetDevice is not None:
        #Add entity
        async_add_entities([MideaDehumidifierDevice(hass, client, targetDevice)])

        _LOGGER.info("midea_dehumidifier: humidifier entity initialized.")
    else:
        _LOGGER.error("midea_dehumidifier: error initializing humidifier entity.")


    #Register services
    #https://community.home-assistant.io/t/registering-a-service/40327/11

    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)

    async def async_service_set_ion_state(call):
        entity_id = call.data[ATTR_ENTITY_ID]
        ion_state = call.data[ATTR_ION_STATE]
        async_dispatcher_send(hass, SERVICE_SET_ION_STATE.format(entity_id), ion_state)
        
    async def async_service_set_mode(call):
        entity_id = call.data[ATTR_ENTITY_ID]
        mode_name = call.data[ATTR_MODE]
        async_dispatcher_send(hass, SERVICE_SET_MODE.format(entity_id), mode_name)

    hass.services.async_register(DOMAIN, SERVICE_SET_FAN_SPEED, async_service_set_fan_speed, SERVICE_SET_FAN_SPEED_SCHEMA)
    hass.services.async_register(DOMAIN, SERVICE_SET_ION_STATE, async_service_set_ion_state, SERVICE_SET_ION_STATE_SCHEMA)
    hass.services.async_register(DOMAIN, SERVICE_SET_MODE, async_service_set_mode, SERVICE_SET_MODE_SCHEMA)

    return True



async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up the Dehumidifier device config entry."""
    await async_setup_platform(hass, {}, async_add_entities)


class MideaDehumidifierDevice(HumidifierEntity):
    """Representation of a Midea/Inventor dehumidifier device."""

    def __init__(self, hass, client, targetDevice):
        _LOGGER.debug("midea_dehumidifier: initializing MideaDehumidifierDevice...")

        self._hass = hass
        self._supported_features = SUPPORT_FLAGS

        #Fan modes
        self._fan_dict = DEHUMI_FAN_SPEED_DICT
        self._fan_list = DEHUMI_FAN_SPEED_LIST

        #Device modes
        self._modes_dict = DEHUMI_MODES_DICT
        self._available_modes = DEHUMI_MODES_LIST

        self._client = hass.data[MIDEA_API_CLIENT + "_" + targetDevice['id']]
        self._device = targetDevice
        self._name = "midea_dehumidifier_"+targetDevice['id']
        self._unique_id = 'midea_dehumidifier_' + targetDevice['id']

        #Default values for device state
        self._powerMode = None          # 0:off, 1:on
        self._mode = None               # device's current mode ['Target_humidity', 'Continuos', 'Smart', 'Dryer']
        self._ionSetSwitch = None       # 0:off, 1:on
        self._humidity = None           # current humidity
        self._humidity_set = None       # target hunidity
        self._humidity_dot = None       # current humidity (decimal)
        self._humidity_dot_set = None   # target humidity (decimal)
        self._windSpeed = None          # fan speed [1..99]
        self._windSpeedMode = None      # fan speed mode (Silent:40, Medium:60, High:80)
        self._isDisplay = None
        self._filterShow = False
        self._tankShow = False
        self._dryClothesSetSwitch = None
        self._upanddownSwing = None

        self._device_class = DEVICE_CLASS_DEHUMIDIFIER

        ##Get appliance's status to set initial values for the device
        #_LOGGER.debug("midea-client: querying appliance status via Web API...")
        #res = self._client.get_device_status(self._device['id'])
        #if res == 1:
        #    _LOGGER.debug("midea_dehumidifier: get_device_status suceeded: "+self._client.deviceStatus.toString())
        #    #Set initial values for device's status
        #    self.__refresh_device_status()
        #else:
        #    _LOGGER.error("midea_dehumidifier: get_device_status error")

    @property
    def unique_id(self):
        """Return the unique id."""
        return self._unique_id

    @property
    def name(self):
        """Return the name of the humidity device."""
        return self._name

    @property
    def supported_features(self):
        """Return the list of supported features."""
        return self._supported_features

    @property
    def should_poll(self):
        """Return the polling state."""
        #get device's status by polling it: Midea Web API lacks of notification capability
        return True

    @property
    def target_humidity(self):
        """Return the humidity we try to reach."""
        return self._humidity_set

    @property
    def mode(self):
        """Return current mode."""
        return self._mode

    @property
    def available_modes(self):
        """Return available modes."""
        return self._available_modes

    @property
    def is_on(self):
        """Return true if the device is on."""
        return self._powerMode

    @property
    def device_class(self):
        """Return the device class of the humidifier."""
        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 the current humidity."""
        return self._humidity

    @property
    def tank_show(self):
        """Return the current Tank Value."""
        return self._tankShow

    @property
    def min_humidity(self):
        """Return the min humidity set."""
        return 40

    @property
    def max_humidity(self):
        """Return the max humidity set."""
        return 85

    @property
    def device_state_attributes(self):
        """Return entity specific state attributes."""
        data = {}

        for prop, attr in PROP_TO_ATTR.items():
            value = getattr(self, prop)
            if value is not None:
                data[attr] = value

        return data


    #####################################################
    #asycn methods 
    #####################################################

    async def async_added_to_hass(self):
        """Run when about to be added to hass."""
        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)

#
#    def __hass_update_state_attribute(self, _state, _attr, _value):
#        """Update attribute on state obtained via hass.states.get() and return dict containing all the state attributes."""
#        data = {}
#        for attr, value in _state.attributes.items():
#            #_LOGGER.info("(attr, value) = (%s,%s)", attr, value)
#            if attr == _attr:
#                data[attr] = _value
#            else:
#                data[attr] = value
#
#        return data
#

    @callback
    async def service_set_fan_speed(self, speed_mode):
        """service_set_fan_speed"""
        _LOGGER.info("service_set_fan_speed called, speed_mode = %s", speed_mode)
        speed = self._fan_dict.get(speed_mode.upper(), 0)
        _LOGGER.info("speed = %s", speed)
        if self.is_on and self._windSpeed != speed and self._client.deviceStatus.setMode != 4:
            _LOGGER.debug("midea-dehumidifier: sending send_fan_speed_command via Web API...")
            res = await self.hass.async_add_executor_job(self._client.send_fan_speed_command, self._device["id"], speed)
            if res is not None:
                _LOGGER.debug("midea-dehumidifier: send_fan_speed_command suceeded: "+self._client.deviceStatus.toString())
                self._windSpeed = speed
                self._windSpeedMode = speed_mode
                
                #Update state attribute
                state = self._hass.states.get('humidifier.'+self._unique_id)
                if state:
                    #attrs = self.__hass_update_state_attribute(state, ATTR_FAN_SPEED_MODE, speed)
                    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):
        """service_set_ion_state"""
        _LOGGER.info("service_set_ion_state called, ion_state = %s", ion_state)
        if self.is_on and self._ionSetSwitch != ion_state:
            if ion_state:
                _LOGGER.debug("midea-dehumidifier: sending send_ion_on_command via Web API...")
                res = await self.hass.async_add_executor_job(self._client.send_ion_on_command, self._device["id"])
            else:
                _LOGGER.debug("midea-dehumidifier: sending send_ion_off_command via Web API...")
                res = await self.hass.async_add_executor_job(self._client.send_ion_off_command, self._device["id"])
            if res is not None:
                _LOGGER.debug("midea-dehumidifier: send_ion_(on/off)_command suceeded: "+self._client.deviceStatus.toString())
                self._ionSetSwitch = ion_state
                #Update state attribute
                state = self._hass.states.get('humidifier.'+self._unique_id)
                if state:
                    #attrs = self.__hass_update_state_attribute(state, ATTR_ION_SET_SWITCH, ion_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_fan_speed_command ERROR.")

    @callback
    async def service_set_mode(self, mode_name):
        """service_set_mode"""
        _LOGGER.info("service_set_mode called, mode_name = %s", mode_name)
        mode = self._modes_dict.get(mode_name.upper(), 0)
        _LOGGER.info("mode = %s", mode)
        if self.is_on and self._mode != mode:
            _LOGGER.debug("midea-dehumidifier: sending send_mode_command via Web API...")
            res = await self.hass.async_add_executor_job(self._client.send_mode_command, self._device["id"], mode)
            if res is not None:
                _LOGGER.debug("midea-dehumidifier: send_mode_command suceeded: "+self._client.deviceStatus.toString())
                self._mode = mode_name
                #Dryer mode set speed_mode to High too
                if mode == 4:    
                    self._windSpeedMode = 'High'
                    self._windSpeed = self._fan_dict.get('HIGH', 0)
                
                #Update state attribute
                state = self._hass.states.get('humidifier.'+self._unique_id)
                if state:
                    attrs = state.attributes.copy()
                    attrs[ATTR_MODE] = mode_name
                    #Dryer mode set speed_mode to High too
                    if mode == 4:
                        attrs[ATTR_FAN_SPEED_MODE] = 'High'
                        attrs[ATTR_FAN_SPEED] = self._fan_dict.get('HIGH', 0)
                    
                    #attrs = self.__hass_update_state_attribute(state, ATTR_MODE, mode)
                    self._hass.states.async_set('humidifier.'+self._unique_id, state.state, attrs, force_update = True)

            else:
                _LOGGER.error("midea-dehumidifier: send_mode_command ERROR.")


    async def async_update(self):
        """Retrieve latest state from the appliance and keep UI updated with respect to the updated status."""
        _LOGGER.info("midea-dehumidifier: async_update called.")
        
        if self._client.security.access_token:
            _LOGGER.debug("midea-dehumidifier: sending get_device_status via Web API...")
            #res = self._client.get_device_status(self._device['id'])
            res = await self.hass.async_add_executor_job(self._client.get_device_status, self._device['id'])
            if res == 1:
                _LOGGER.info(self._device['id']+" - "+self._client.deviceStatus.toString())
                #Refresh device status
                self.__refresh_device_status()
            else:
                _LOGGER.error("midea-dehumidifier: get_device_status ERROR.")


    def __refresh_device_status(self):
        """Called by async_update(self): keep UI updated with respect to the updated status."""
        if self._client.deviceStatus is not None:
            self._powerMode = self._client.deviceStatus.powerMode
            self._ionSetSwitch = self._client.deviceStatus.ionSetSwitch

            #Current mode
            #self._mode = self._client.deviceStatus.setMode
            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

            #Useful or useless ?
            #self.async_update_ha_state()
            #self.async_schedule_update_ha_state()

            #PROVE
            #async_update_entity(self._hass, self._name)
            #async_update_entity(self._hass, 'humidifier.midea_dehumidifier_17592186063322')
            #ALTERNATIVA DA PROVARE: self.async_update_entity(self._hass, self._unique_id)

#            state = hass.states.get(entity_id)
#            if state:
#                attrs = state.attributes
#            self._hass.states.set(self._unique_id, state, state.attributes, force_update=True)


    async def async_turn_on(self, **kwargs):
        """Turn the device on."""
        _LOGGER.info("midea-dehumidifier:async_turn_on called.")
        if not self.is_on:
            _LOGGER.debug("midea-dehumi: sending power-on command via Web API...")
            #res = self._client.send_poweron_command(self._device["id"])
            res = await self.hass.async_add_executor_job(self._client.send_poweron_command, self._device["id"])
            if res is not None:
                _LOGGER.debug("midea-dehumidifier: send_poweron_command suceeded: "+self._client.deviceStatus.toString())
                #Refresh device status
                self.__refresh_device_status()
            else:
                _LOGGER.error("midea-dehumidifier: send_poweron_command ERROR.")


    async def async_turn_off(self, **kwargs):
        """Turn the device off."""
        _LOGGER.info("midea-dehumidifier: async_turn_off called.")
        if self.is_on:
            _LOGGER.debug("midea-dehumi: sending power-off command via Web API...")
            #res = self._client.send_poweroff_command(self._device["id"])
            res = await self.hass.async_add_executor_job(self._client.send_poweroff_command, self._device["id"])
            if res is not None:
                _LOGGER.debug("midea-dehumidifier: send_poweroff_command suceeded: "+self._client.deviceStatus.toString())
                #Refresh device status
                self.__refresh_device_status()
            else:
                _LOGGER.error("climate.midea-dehumi: send_poweroff_command ERROR.")


    async def async_set_humidity(self, humidity):
        """Set new humidity level."""
        _LOGGER.info("midea-dehumidifier: async_set_humidity called.")
        if self.is_on:
            if self._humidity_set != humidity:
                _LOGGER.debug("midea-dehumidifier: setting new target hunidity value via Web API...")
                #res = self._client.send_target_humidity_command(self._device["id"], humidity)
                res = await self.hass.async_add_executor_job(self._client.send_target_humidity_command, self._device["id"], humidity)
                if res is not None:
                    _LOGGER.info("midea-dehumidifier: send_target_humidity_command succeeded: "+self._client.deviceStatus.toString())
                    #Refresh device status
                    self.__refresh_device_status()
                else:
                    _LOGGER.error("midea-dehumidifier: send_target_humidity_command ERROR")


    async def async_set_mode(self, mode):
        """Update mode."""
        _LOGGER.info("midea-dehumidifier: async_set_mode called; current_mode=%s, new mode=%s", self._mode, mode)
        if self.is_on:
            mode_num = self._modes_dict.get(mode.upper(), 0)            
            _LOGGER.debug("midea-dehumi: sending update status command via Web API...")
            #res = self._client.send_mode_command(self._device["id"], mode_num)
            res = await self.hass.async_add_executor_job(self._client.send_mode_command, self._device["id"], mode_num)
            if res is not None:
                _LOGGER.debug("midea-dehumidifier: send_mode_command suceeded: "+self._client.deviceStatus.toString())
                self._client.deviceStatus._setMode = mode_num
                #Refresh device status
                self.__refresh_device_status()
            else:
                _LOGGER.error("climate.midea-dehumi: send_mode_command ERROR.")


Hello, do you get any info about compatibility of Atmosphere with this component?

Update: Inventor Atmosphere use Tuya as communication, so you can use TuyaSmart app instead
Inventor Control. Even Tuya has a native support in HA, the Tuya dehumidifier’s doesn’t supported yet, so you can just have scenes defined in Tuya which you can trigger from HA but this is one way communication. I hope HA will get support for Tuya dehumidifier’s in the near feature.

1 Like

Hello fellow home-assistant enthusiasts!
I have a quick question, did anybody (or is it even possible?) used a Wemos Mini (Esp8266) and Tasmota to controll the device cloud-free?
I have found projects for ESP8266 but not with the Wemos version or Tasmota

Update:
I got the cloud-free control through https://github.com/Hypfer/esp8266-midea-dehumidifier
I also didn’t use a USB Adapter since I cut the USB female connector and connected direct the cables on ESP-01

1 Like

Hello! A couple of days now the integration stopped working. I believe something changed to the midea API.

Problem resolved without any changes.

Problem integation log pase:

Logger: homeassistant.setup
Source: setup.py:308
First occurred: 20:52:44 (2 occurrences)
Last logged: 20:52:45

  • Unable to prepare setup for platform midea_dehumidifier.sensor: Platform not found (cannot import name ‘ATTR_MODE’ from ‘homeassistant.components.humidifier.const’ (/usr/src/homeassistant/homeassistant/components/humidifier/const.py)).
  • Unable to prepare setup for platform midea_dehumidifier.humidifier: Platform not found (cannot import name ‘ATTR_MODE’ from ‘homeassistant.components.humidifier.const’ (/usr/src/homeassistant/homeassistant/components/humidifier/const.py)).

My product Inventor Eva II PRO WiFi, everything was working so far with HACS

Help, please…

My sistem:

Versión core-2021.4.3
Tipo de instalación Home Assistant OS
Desarrollo false
Supervisor true
Docker true
Entorno virtual false
Versión de Python 3.8.7
Nombre del Sistema Operativo Linux
Versión del Sistema Operativo 5.4.83-v7l
Arquitectura de CPU armv7l
Zona horaria Europe/Madrid