PROKLIMA-A018-12KR2/C portable air conditioner fully working with localtuya

This is a mobile air conditioner, a generic device sold in Spain by the Bauhaus stores as PROKLIMA-A018-12KR2/C.

Captura de pantalla 2023-03-06 173601

Functions:

  • Modes: Cool, Dry, Fan, Sleep
  • Fan Speeds: 3
  • Vertical Swing
  • Temperature range: 16 to 31

DP LIST

DP Name Type
1 Power
2 Set Temperature ºC
3 Room Temperature ºC
4 Mode
5 Fan Speed
103 Sleep boolean
104 Synchronization in min
105 Out of time min
11 Purify boolean
107 Set Temperature
108 Room Temperature
109 Indicador de función
110 Horizontal Oscillation boolean
15 Vertical Oscillation
20 Fault

It is necessary to modify climate.py, because actually localtuya doesn’t support air conditioning.

And for the min and max temperature it is necessary to modify also const.py and en.json. this is not really necessary, only in case you want it more polished.

I used as reference:

climate.py MODIFICATIONS

About line 13:

from homeassistant.components.climate.const import (
    CURRENT_HVAC_HEAT,
    CURRENT_HVAC_IDLE,
    CURRENT_HVAC_COOL,
    HVAC_MODE_COOL,
    HVAC_MODE_DRY,
    HVAC_MODE_FAN_ONLY,
    HVAC_MODE_AUTO,
    HVAC_MODE_HEAT,
    HVAC_MODE_OFF,
    PRESET_AWAY,
    PRESET_ECO,
    PRESET_HOME,
    PRESET_NONE,
    SUPPORT_PRESET_MODE,
    SUPPORT_TARGET_TEMPERATURE,
    SUPPORT_TARGET_TEMPERATURE_RANGE,
)

I added the following :

CURRENT_HVAC_COOL,
HVAC_MODE_COOL,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,

About line 59:

HVAC_MODE_SETS = {
    "manual/auto": {
        HVAC_MODE_HEAT: "manual",
        HVAC_MODE_AUTO: "auto",
    },
    "Manual/Auto": {
        HVAC_MODE_HEAT: "Manual",
        HVAC_MODE_AUTO: "Auto",
    },
    "Manual/Program": {
        HVAC_MODE_HEAT: "Manual",
        HVAC_MODE_AUTO: "Program",
    },
    "m/p": {
        HVAC_MODE_HEAT: "m",
        HVAC_MODE_AUTO: "p",
    },
    "True/False": {
        HVAC_MODE_HEAT: True,
    },
    "1/0": {
        HVAC_MODE_HEAT: "1",
        HVAC_MODE_AUTO: "0",
    },
    "True/False (Cool)": {
        HVAC_MODE_HEAT: True,
    },
    "auto/cold/wet/fan": {
        HVAC_MODE_COOL: "cold",
        HVAC_MODE_DRY: "wet",
        HVAC_MODE_FAN_ONLY: "wind",
    },
}

I added the following mode_set:

“auto/cold/wet/fan”: {
HVAC_MODE_COOL: “cold”,
HVAC_MODE_DRY: “wet”,
HVAC_MODE_FAN_ONLY: “wind”,
},

Cold, wet and wind are specific for this device, in some other model maybe you must put fan instead of wind (check the DPS for this)

About line 59:

HVAC_ACTION_SETS = {
    "True/False": {
        CURRENT_HVAC_HEAT: True,
        CURRENT_HVAC_COOL: True,
        CURRENT_HVAC_IDLE: False,
    },
    "open/close": {
        CURRENT_HVAC_HEAT: "open",
        CURRENT_HVAC_COOL: "open",
        CURRENT_HVAC_IDLE: "close",
    },
    "heating/no_heating": {
        CURRENT_HVAC_HEAT: "heating",
        CURRENT_HVAC_IDLE: "no_heating",
    },
    "Heat/Warming": {
        CURRENT_HVAC_HEAT: "Heat",
        CURRENT_HVAC_IDLE: "Warming",
    },
    "cooling/no_cooling": {
        CURRENT_HVAC_COOL: "cooling",
        CURRENT_HVAC_IDLE: "no_cooling",
    }, 
}

About line 238:

    @property
    def hvac_action(self):
        """Return the current running hvac operation if supported.

        Need to be one of CURRENT_HVAC_*.
        """
        if self._config.get(CONF_HEURISTIC_ACTION, False):
            if self._hvac_mode == HVAC_MODE_HEAT:
                if self._current_temperature < (
                    self._target_temperature - self._precision
                ):
                    self._hvac_action = CURRENT_HVAC_HEAT
                if self._current_temperature == (
                    self._target_temperature - self._precision
                ):
                    if self._hvac_action == CURRENT_HVAC_HEAT:
                        self._hvac_action = CURRENT_HVAC_HEAT
                    if self._hvac_action == CURRENT_HVAC_IDLE:
                        self._hvac_action = CURRENT_HVAC_IDLE
                if (
                    self._current_temperature + self._precision
                ) > self._target_temperature:
                    self._hvac_action = CURRENT_HVAC_IDLE
            return self._hvac_action
            if self._hvac_mode == HVAC_MODE_COOL:
                if self._current_temperature < (
                    self._target_temperature - self._precision
                ):
                    self._hvac_action = CURRENT_HVAC_COOL
                if self._current_temperature == (
                    self._target_temperature - self._precision
                ):
                    if self._hvac_action == CURRENT_HVAC_COOL:
                        self._hvac_action = CURRENT_HVAC_COOL
                    if self._hvac_action == CURRENT_HVAC_IDLE:
                        self._hvac_action = CURRENT_HVAC_IDLE
                if (
                    self._current_temperature + self._precision
                ) > self._target_temperature:
                    self._hvac_action = CURRENT_HVAC_IDLE
            return self._hvac_action         
        return self._hvac_action

    @property

MODIFICATIONS TO SET MIN AND MAX TEMPERATURE:

In climate.py

from .common import LocalTuyaEntity, async_setup_entry
from .const import (
    CONF_CURRENT_TEMPERATURE_DP,
    CONF_ECO_DP,
    CONF_ECO_VALUE,
    CONF_HEURISTIC_ACTION,
    CONF_HVAC_ACTION_DP,
    CONF_HVAC_ACTION_SET,
    CONF_HVAC_MODE_DP,
    CONF_HVAC_MODE_SET,
    CONF_TEMP_MAX,
    CONF_TEMP_MIN,
    CONF_MAX_TEMP_DP,
    CONF_MIN_TEMP_DP,
    CONF_PRECISION,
    CONF_PRESET_DP,
    CONF_PRESET_SET,
    CONF_TARGET_PRECISION,
    CONF_TARGET_TEMPERATURE_DP,
    CONF_TEMPERATURE_STEP,
)

And also:

def flow_schema(dps):
    """Return schema used in config flow."""
    return {
        vol.Optional(CONF_TARGET_TEMPERATURE_DP): vol.In(dps),
        vol.Optional(CONF_CURRENT_TEMPERATURE_DP): vol.In(dps),
        vol.Optional(CONF_TEMPERATURE_STEP): vol.In(
            [PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
        ),
        vol.Optional(CONF_TEMP_MIN, default=DEFAULT_MIN_TEMP): vol.Coerce(float),
        vol.Optional(CONF_TEMP_MAX, default=DEFAULT_MAX_TEMP): vol.Coerce(float),
        vol.Optional(CONF_MAX_TEMP_DP): vol.In(dps),
        vol.Optional(CONF_MIN_TEMP_DP): vol.In(dps),
        vol.Optional(CONF_PRECISION): vol.In(
            [PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
        ),
        vol.Optional(CONF_HVAC_MODE_DP): vol.In(dps),
        vol.Optional(CONF_HVAC_MODE_SET): vol.In(list(HVAC_MODE_SETS.keys())),
        vol.Optional(CONF_HVAC_ACTION_DP): vol.In(dps),
        vol.Optional(CONF_HVAC_ACTION_SET): vol.In(list(HVAC_ACTION_SETS.keys())),
        vol.Optional(CONF_ECO_DP): vol.In(dps),
        vol.Optional(CONF_ECO_VALUE): str,
        vol.Optional(CONF_PRESET_DP): vol.In(dps),
        vol.Optional(CONF_PRESET_SET): vol.In(list(PRESET_SETS.keys())),
        vol.Optional(CONF_TEMPERATURE_UNIT): vol.In(
            [TEMPERATURE_CELSIUS, TEMPERATURE_FAHRENHEIT]
        ),
        vol.Optional(CONF_TARGET_PRECISION): vol.In(
            [PRECISION_WHOLE, PRECISION_HALVES, PRECISION_TENTHS]
        ),
        vol.Optional(CONF_HEURISTIC_ACTION): bool,
    }

And also:

    @property
    def min_temp(self):
        """Return the minimum temperature."""
        if self.has_config(CONF_MIN_TEMP_DP):
            return self.dps_conf(CONF_MIN_TEMP_DP)
        if self.has_config(CONF_TEMP_MIN):
            return self._config[CONF_TEMP_MIN]
        return DEFAULT_MIN_TEMP

    @property
    def max_temp(self):
        """Return the maximum temperature."""
        if self.has_config(CONF_MAX_TEMP_DP):
            return self.dps_conf(CONF_MAX_TEMP_DP)
        if self.has_config(CONF_TEMP_MAX):
            return self._config[CONF_TEMP_MAX]
        return DEFAULT_MAX_TEMP

In const.py

# climate
CONF_TARGET_TEMPERATURE_DP = "target_temperature_dp"
CONF_CURRENT_TEMPERATURE_DP = "current_temperature_dp"
CONF_TEMPERATURE_STEP = "temperature_step"
CONF_TEMP_MAX = "max_temp"
CONF_TEMP_MIN = "min_temp"
CONF_MAX_TEMP_DP = "max_temperature_dp"
CONF_MIN_TEMP_DP = "min_temperature_dp"
CONF_PRECISION = "precision"
CONF_TARGET_PRECISION = "target_precision"
CONF_HVAC_MODE_DP = "hvac_mode_dp"
CONF_HVAC_MODE_SET = "hvac_mode_set"
CONF_PRESET_DP = "preset_dp"
CONF_PRESET_SET = "preset_set"
CONF_HEURISTIC_ACTION = "heuristic_action"
CONF_HVAC_ACTION_DP = "hvac_action_dp"
CONF_HVAC_ACTION_SET = "hvac_action_set"
CONF_ECO_DP = "eco_dp"
CONF_ECO_VALUE = "eco_value"

In \translations\en.json
About line 176:

                    "max_temperature_dp": "Max Temperature (optional)",
                    "min_temperature_dp": "Min Temperature (optional)",
                    "max_temp": "Max Temperature Manual (optional)",
                    "min_temp": "Min Temperature Manual (optional)",
                    "precision": "Precision (optional, for DPs values)",
                    "target_precision": "Target Precision (optional, for DPs values)",

ADDING THE DEVICE TO LOCALTUYA INTEGRATION

Configuration → Add a new device →

Name Cooler (or whatever)
ID 1
Target Temperature 2
Current Temperature: 17
Temperature Step 1
(The 2 following options in case you made the modifications for the temperature set)
Min Temperature Manual (optional) 16
Max Temperature Manual (optional) 31
Precision (optional, for DPS values) 1
HVAC Mode DP (optional) 4
HVAC Mode Set (optional) auto/cold/wet/fan
HVAC Current Action Set (optional) cooling/no_cooling
Eco DP (optional) 103
Eco value (optional) True
Temperature Unit Choose one
Target Precision 1

Fill all the entries, click SEND, and VERY IMPORTANT, in the next screen UNCHECK “Do not add more entities”

Here we are going to add some missing sensor, switch and selector related to the device, for example the Mode Selector.

Choose “select” and then SEND

Select DP 4

Valid entries, separate entries by a ;: cold;wet;wind

User Friendly options: Cold;Dehumidifier;Fan (or whatever you want)

Click on SEND, uncheck again “Do not add more entities”, then add the next entity and so on.

ENTITIES TO ADD:

Use the same name as you use to name the device, in this way the name disappears from the name of the entity but not from the description of it.
You will have a selector named Mode and an entity named select.cooler_mode

DPS Type Value Name Friendly Name
4 select cold;wet;wind Cooler Mode Cold;Dehumidier;Fan
103 switch Cooler Sleep / ECO
5 select low;med;high Cooler Fan Speed Low;Mid;High
110 switch Cooler Oscilator
20 sensor Cooler Failures

And that’s all.

2 Likes

Thank you. I would just like to add for anyone using a TCL airconditioner that runs off the smartlife app, these instructions also work (at least in part) with that system. I have not perfected it yet, but finally its working for me!

2 Likes

Also wanted to say thanks for sharing this, was really helpful and worked flawlessly :slight_smile:

1 Like

@oooshk @uriirichard

I wonder if perhaps I could get more guidance as I am facing some issues:

I have Haverland TAC-1223WC also known as TCL P12F3SW0K

Tuya .py and .json files edited as described (a few indent were wrong that were corrected)
Unit is then picked up by LocalTuya after entering Tuya IOT credentials -

How does one match DP instruction numbers ?

Here is what I see about the device in the Tuya IOT:

I am looking at some help to understand what the numbers mean for this AC …or how does one work out what is what…:wink:

Right, think I have now worked it out.

For anyone else wondering the same, the information about the LocalTuya DP instructions detected can be understood from the Tuya Iot cloud explorer page where one can see the device under the tuya “kt” category which defines the various options for the DPs:
Standard Instruction Set-Tuya IoT Development Platform-Tuya Developer.


This is what I have gathered for my particular model:

I am getting an error about “PRESET_SETS” not defined…Any ideas ?

  File "/config/custom_components/localtuya/climate.py", line 155, in flow_schema
    vol.Optional(CONF_PRESET_SET): vol.In(list(PRESET_SETS.keys())),
                                               ^^^^^^^^^^^
NameError: name 'PRESET_SETS' is not defined

I have commented-out the line mentionned above and I am getting slowly there but am struggling to present the “climate” entity like your have withthe card above that I presume is the “Thermostat” card ?

@uriirichard
Not sure why the Thermostat card will not load the data like you are showing above…
Here is a video of where I got to with trial and errors:
Haverland TAC1223WC LocalTuya control
Mode control (cool/fan/dehumidify) = working
Louver oscillation = working
Fan speed (auto/low/high) = working

Not working:
ON/OFF missing ?
SEt_Temp_Celcius : once changed it goes straight to +32C and stays there…?

i am new to HA and do not have a dev background. if this is not the correct solution, feel free to correct me

the modes and fans were not working properly on my proklima-a018a-12c1-w. it seems like i had to use numbers instead for the values, even though Tuya cloud told me the values were as stated in the original post:

mode	Enum	
{
  "range": [
    "auto",
    "cold",
    "hot",
    "wet",
    "wind",
    "eco"
  ]
}

so instead, i had to do this in climate.py:

    "cold/wet/fan": {
        HVAC_MODE_COOL: "1",
        HVAC_MODE_DRY: "3",
        HVAC_MODE_FAN_ONLY: "5",
    },

for the entities added, had to do the same:

  • for mode, instead of using cold;wet;wind, had to use 1;3;5
  • for fan speed, instead of using low;med;high, had to use 3;2;1

my unit supports a timer, and i am now wondering how to make it work. if you have any feedback, i would appreciate it:

Code DP ID Type Potential Values
time 105 Integer Timer setting (varies, often in minutes)