I have this Tuya device (Moes S16Pro) which is used to control AC units. I flashed it with ESPHome via Cloud cutter (more info here). The way it works is that it has a main Climate device as a TuyaClimate entity, and a secondary IR Climate entity to relay the changes from the primary entity as IR commands to the AC. It works pretty well. However, there is a functionaluty present on the original Tuya firmware which I’m strugling to make it work: The device could read IR commands from the original IR controller and stay in sync with it, so you could use both controll methods in parallel. Here is the current yaml I have:
esphome:
name: termostato-criancas
friendly_name: Termostato Crianças
bk72xx:
board: generic-bk7231n-qfn32-tuya
# Enable logging
logger:
# level: INFO
# Enable Home Assistant API
api:
encryption:
key: ""
ota:
- platform: esphome
password: ""
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Termostato-Criancas Hotspot"
password: ""
captive_portal:
########################
### IR BLASTER SETUP ###
########################
remote_transmitter:
id: ir_t
pin: P7
carrier_duty_percent: 50%
remote_receiver:
id: ir_r
pin:
number: P8
inverted: true
dump:
#- lg
#- raw
tolerance: 55%
######################
### TUYA MCU SETUP ###
######################
uart:
rx_pin: RX1
tx_pin: TX1
baud_rate: 9600
tuya:
###############
### SENSORS ###
###############
sensor:
- platform: tuya
name: "Umidade"
sensor_datapoint: 12
unit_of_measurement: "%"
- platform: tuya
name: "Temperatura"
sensor_datapoint: 2
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
#######################
### CLIMATE DEVICES ###
#######################
climate:
# THIS IS THE TUYA CLIMATE ENTITY
# IT RELAYS STATE CHANGES TO THE SECONDARY CLIMATE ENTITY WHICH PROCESSES THEM AS IR COMMANDS
- platform: tuya
name: "AC"
id: climate_primary
visual:
min_temperature: 17
max_temperature: 30
temperature_step: 1
switch_datapoint: 1
target_temperature_datapoint: 3
target_temperature_multiplier: 1
current_temperature_datapoint: 2
current_temperature_multiplier: 0.1
supports_heat: true
supports_cool: true
active_state:
datapoint: 4
cooling_value: 0
heating_value: 1
fanonly_value: 3
drying_value: 4
fan_mode:
datapoint: 5
auto_value: 0
low_value: 1
medium_value: 2
high_value: 3
# AUTOMATION THAT WHENEVER THE DATAPOINTS UPDATE THOSE STATUSES SHOULD ALSO BE UPDATED ON THE MAIN CLIMATE ENTITY
on_state:
- lambda: |-
if (id(climate_primary).mode != (id(climate_secondary).mode)) {
auto call = id(climate_secondary).make_call();
call.set_mode(id(climate_primary).mode);
call.perform();
}
else if (id(climate_primary).fan_mode != (id(climate_secondary).fan_mode)) {
auto call = id(climate_secondary).make_call();
call.set_fan_mode(id(climate_primary).fan_mode);
call.perform();
}
else if (id(climate_primary).target_temperature != (id(climate_secondary).target_temperature)) {
auto call = id(climate_secondary).make_call();
call.set_target_temperature(id(climate_primary).target_temperature);
call.perform();
}
# - lambda: |-
# if ((id(climate_secondary).swing_mode) != CLIMATE_SWING_BOTH) {
# auto call = id(climate_secondary).make_call();
# call.set_swing_mode(CLIMATE_SWING_BOTH);
# call.perform();
# }
# THIS THE THE SECONDARY HIDDEN CLIMATE DEVICE THAT PROCESSES THE COMMANDS FROM THE PRIMARY ENTITY AS IR COMMANDS
- platform: climate_ir_lg
name: "IR"
id: climate_secondary
header_high: 3265us # AC Units from LG in Brazil use these timings
header_low: 9856us
receiver_id: ir_r
on_state:
- lambda: |-
# Code to sync back states received from IR controller would go here
This code is working right now, the syncroniztion work in one way (primary > secondary). The primary climate entity is the one exposed in HA. any commands entered via HA or via the touch panel of the device itself are propagated to the secondary climate entity and transmited as IR commands.
In the secondary entity I’m using the receiver_id property to map the IR receiver, and I can see via logs that the commands from the controller are interpreted correcly and states on the secondary climate entity are updated accordingly. So the only missing part is making it propagate back to primary climate. I tried doing it via on_state
attriburte in the secondary, but I think this causes an infinite loop which makes the device unresponsive. On my first attempt testing a sync back, I tought I had bricked the device because I coudn’t OTA it again, but thanks to safe mode I was able to recover. Now I’m afraid to test any other code
Anyway, I need help figuring out how I could keep both entities in sync without entering on a infinite loop again. Also, is there an alternative way to test this code without risking to render the device unresponsive again?