Tuya climate integration

Am trying to get the new Tuya integration working with my heating however I’m not having much luck.

The device shows in the SmartLife app and is showing in my project in the Tuya dev dashboard. The device also shows in HA however it shows as OFF and the shown set value is incorrect - SmartLife shows 18 (centigrade) in HA it shows 3.6. If you work it out it’s basically doubling the value (18 becomes 36) and then shifting the decimal to the left (3.6).

Debugging in Tuya dashboard also shows the value as double (36) and in the logs it’s publishing 3.6 (deg centigrade).

HA is showing the set change instantly but does not allow me to change the setting, I also cannot set the operation state in HA - there is no option.

I have tried adding a new project, following the new guides and have removed all remnants of any previous Tuya config from my HA.

What am I missing, or is this just a bug that hopefully will get resolved soon? Just to add, my HA Tuya Custom code (from HACS) broke a few days ago when the Tuya global outage occurred and hasn’t worked since, apart from by using the SmartLife app. This might be related.
Thanks
Nic

2 Likes

with a file editor you can change this file and all work again I had the same problem to fix.

/config/custom_components/tuya_v2/climate.py

@property
def temperature_unit(self) -> str:
    """Return true if fan is on."""
    if self.__is_celsius():
        return TEMP_CELSIUS
    return TEMP_FAHRENHEIT

@property
def current_temperature(self) -> float:
    """Return the current temperature."""
    if (
        DPCODE_TEMP_CURRENT not in self.tuya_device.status
        and DPCODE_TEMP_CURRENT_F not in self.tuya_device.status
    ):
        return None

    if self.__is_celsius():
        return (
            self.tuya_device.status.get(DPCODE_TEMP_CURRENT, 0)
            * 1.0
            / (2 ** self.get_temp_current_scale())
        )
    return (
        self.tuya_device.status.get(DPCODE_TEMP_CURRENT_F, 0)
        * 1.0
        / (2 ** self.get_temp_current_scale())
    )

@property
def current_humidity(self) -> int:
    """Return the current humidity."""
    return int(self.tuya_device.status.get(DPCODE_HUMIDITY_CURRENT, 0))

@property
def target_temperature(self) -> float:
    """Return the temperature currently set to be reached."""
    return (
        self.tuya_device.status.get(DPCODE_TEMP_SET, 0)
        * 1.0
        / (2 ** self.get_temp_set_scale())
    )

@property
def max_temp(self) -> float:
    """Return the maximum temperature."""
    return self.target_temperature_high

@property
def min_temp(self) -> float:
    """Return the minimum temperature."""
    return self.target_temperature_low

@property
def target_temperature_high(self) -> float:
    """Return the upper bound target temperature."""
    if self.__is_celsius():
        if DPCODE_TEMP_SET not in self.tuya_device.function:
            return 0
        temp_value = json.loads(
            self.tuya_device.function.get(DPCODE_TEMP_SET, {}).values
        )
        return temp_value.get("max", 0) * 1.0 / (2 ** self.get_temp_set_scale())
    if DPCODE_TEMP_SET_F not in self.tuya_device.function:
        return 0
    temp_value = json.loads(
        self.tuya_device.function.get(DPCODE_TEMP_SET_F, {}).values
    )
    return temp_value.get("max", 0) * 1.0 / (2 ** self.get_temp_set_scale())

@property
def target_temperature_low(self) -> float:
    """Return the lower bound target temperature."""
    if self.__is_celsius():
        if DPCODE_TEMP_SET not in self.tuya_device.function:
            return 0
        temp_value = json.loads(
            self.tuya_device.function.get(DPCODE_TEMP_SET, {}).values
        )
        low_value = (
            temp_value.get("min", 0) * 1.0 /
            (2 ** self.get_temp_set_scale())
        )
        return low_value
    if DPCODE_TEMP_SET_F not in self.tuya_device.function:
        return 0
    temp_value = json.loads(
        self.tuya_device.function.get(DPCODE_TEMP_SET_F, {}).values
    )
    return temp_value.get("min", 0) * 1.0 / (2 ** self.get_temp_set_scale())

@property
def target_temperature_step(self) -> float:
    """Return target temperature setp."""
    if (
        DPCODE_TEMP_SET not in self.tuya_device.status_range
        and DPCODE_TEMP_SET_F not in self.tuya_device.status_range
    ):
        return 1.0
    __temp_set_value_range = json.loads(
        self.tuya_device.status_range.get(
            DPCODE_TEMP_SET if self.__is_celsius() else DPCODE_TEMP_SET_F
        ).values
    )
    return (
        __temp_set_value_range.get("step", 0)
        * 1.0
        / (2 ** self.get_temp_set_scale())
    )

@property
def target_humidity(self) -> int:
    """Return target humidity."""
    return int(self.tuya_device.status.get(DPCODE_HUMIDITY_SET, 0))

@property
def hvac_mode(self) -> str:
    """Return hvac mode."""
    if not self.tuya_device.status.get(DPCODE_SWITCH, False):
        return HVAC_MODE_OFF
    if DPCODE_MODE not in self.tuya_device.status:
        return HVAC_MODE_OFF
    return TUYA_HVAC_TO_HA[self.tuya_device.status.get(DPCODE_MODE)]

@property
def hvac_modes(self) -> List:
    """Return hvac modes for select."""
    if DPCODE_MODE not in self.tuya_device.function:
        return []
    modes = json.loads(self.tuya_device.function.get(DPCODE_MODE, {}).values).get(
        "range"
    )

    _LOGGER.debug(f"hvac_modes->{modes}")
    hvac_modes = [HVAC_MODE_OFF]
    for tuya_mode, ha_mode in TUYA_HVAC_TO_HA.items():
        if tuya_mode in modes:
            hvac_modes.append(ha_mode)

    return hvac_modes

@property
def preset_modes(self) -> list:
    """Return available presets."""
    if DPCODE_MODE not in self.tuya_device.function:
        return []
    modes = json.loads(self.tuya_device.function.get(DPCODE_MODE, {}).values).get(
        "range"
    )
    preset_modes = filter(lambda d: d not in TUYA_HVAC_TO_HA.keys(), modes)
    return list(preset_modes)

@property
def fan_mode(self) -> str:
    """Return fan mode."""
    return self.tuya_device.status.get(DPCODE_FAN_SPEED_ENUM)

@property
def fan_modes(self) -> List[str]:
    """Return fan modes for select."""
    data = json.loads(
        self.tuya_device.function.get(DPCODE_FAN_SPEED_ENUM, {}).values
    ).get("range")
    return data

@property
def swing_mode(self) -> str:
    """Return swing mode."""
    mode = 0
    if (
        DPCODE_SWITCH_HORIZONTAL in self.tuya_device.status
        and self.tuya_device.status.get(DPCODE_SWITCH_HORIZONTAL)
    ):
        mode += 1
    if (
        DPCODE_SWITCH_VERTICAL in self.tuya_device.status
        and self.tuya_device.status.get(DPCODE_SWITCH_VERTICAL)
    ):
        mode += 2

    if mode == 3:
        return SWING_BOTH
    if mode == 2:
        return SWING_VERTICAL
    if mode == 1:
        return SWING_HORIZONTAL
    return SWING_OFF

@property
def swing_modes(self) -> List:
    """Return swing mode for select."""
    return [SWING_OFF, SWING_HORIZONTAL, SWING_VERTICAL, SWING_BOTH]

@property
def supported_features(self):
    """Flag supported features."""
    supports = 0
    if (
        DPCODE_TEMP_SET in self.tuya_device.status
        or DPCODE_TEMP_SET_F in self.tuya_device.status
    ):
        supports = supports | SUPPORT_TARGET_TEMPERATURE
    if DPCODE_FAN_SPEED_ENUM in self.tuya_device.status:
        supports = supports | SUPPORT_FAN_MODE
    if DPCODE_HUMIDITY_SET in self.tuya_device.status:
        supports = supports | SUPPORT_TARGET_HUMIDITY
    if (
        DPCODE_SWITCH_HORIZONTAL in self.tuya_device.status
        or DPCODE_SWITCH_VERTICAL in self.tuya_device.status
    ):
        supports = supports | SUPPORT_SWING_MODE
    return supports

Blockquote

changed this see now show the right temperature.
Changed all /10 to /2 and work perfect now.

18 x 2 = 36 after /2 show 18

@dustardly2 thank you for the suggestion, and this is what I previously did with the custom Tuya code (from HACS), however this relates to the new integrated Tuya service in HA 2021.10.x meaning this is either an issue in the Tuya code or HA (edit: or my setup!).

Is anyone else experiencing the same issue or if not any suggestions on how I troubleshoot this?
Thanks

This FIX is FOR TUYA v2! FIX is on configuration of TUYA v2. Is very similar to old bug , but fix our thermostat. I’m using TUYA v2 on HA 2021.10.x and it fixed my bug. Old fix was for tuya v1 not v2 and changed only 1 float number in this new fix I changed all variable to fix .It was very similar but code was different. I have wrote all code changed easy to replace the part copy & paste the wrong code or just change all variable with an editor.

@dustardly2 are you saying don’t use the new ‘integrated’ Tuya code, but install Tuya v2 from HACS and modify it?
I tried this a week ago when I was attempting to configure ‘local Tuya’ which meant installing Tuya v2, only ‘climate’ was not supported. It sounds like I was a week too early - perhaps they’ve updated the code since then. I’ll try your suggestion. Many thanks.

@dustardly2 ok added Tuya_v2 from HACS, modified the climate.py file and restarted HA. Then went to Integrations and deleted Tuya and then when adding a new integration I searched for Tuya but only ‘Tuya’ comes up, no Tuya v2, which is odd but perhaps the custom code takes precedence? Anyway added but still shows the wrong values:
Screenshot 2021-10-10 at 11.33.10

I suspect I’m doing something wrong?

I uninstalled tuya , reboot after installed Tuya 2 and config with all key that ask, after see if it work , after change climate.py and reboot

hello sorry I’m a beginner I don’t understand what I need to modify you can put the climate.py file already modified thank you very kind school of my english I used a translator

Hi there. I’m experiencing the same @dustardly2 problem. I unistalled the old Tuya integration ans installed the new Tuya V.2.(I also have the Local Tuya in HACS). I do not have the /config/custom_components/tuya_v2/climate.py directory and file, so I don’t know how to proceed to fix the wrong showed temperature. Any other suggestions? @Paulus, @frenck Why we have to find workaround for an official integration? Can someone fix it in a next release? Thanks.

At the moment neither tuya 1 nor tuya 2 is working for me. I did the whole procedure on the Cloud, but nothing. Updated to 2021.11. The only way to use the switches was to install LocalTuya integration from HACS. I can’t install the thermostat. Anyone know what’s going on?

I’m having the same issue: went straight to the new HA Tuya integration, added a climate entity which is not working.

Would be good to get the official integration to work, so have raised a ticket: Tuya official integration not working on a "ReadyWarm Crystal" heater · Issue #59548 · home-assistant/core · GitHub

Having the same issue.

  1. Correct status is not shown
  2. No control on the device
  3. No precision (24.5 shown as 245)

Anyone found a fix?

1 Like

Hello vdigo,

Localtuya integration is working with Ready Warm Cristal heater. You need to configure it correctly. The only option I couldn’t set correctly is timer, I can only see it as a sensor.

First you have to gain access to Tuya IoT platform and with obtained credentials you have to create a localtuya integration. You need to create 3 entities: “climate”, “select” to be able to modify operating mode (500W or 1000W) and sensor to indicate the auto-off timer time.