So i managed to flash a BHT-002 two-pipe fan-coil thermostat with ESPHome and this template:
Please see my config here:
esphome:
name: thermostat
friendly_name: Thermostat
bk72xx:
board: generic-bk7231n-qfn32-tuya
# Enable logging
logger:
level: DEBUG
# 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: "Thermostat Fallback Hotspot"
password: "..."
captive_portal:
uart:
rx_pin: RX1
tx_pin: TX1
baud_rate: 9600
time:
- platform: homeassistant
id: ha_time
tuya:
# The MCU uses this for displaying the time in the display as well as for
# scheduled programmes one may have configured in their thermostat.
time_id: ha_time
# (Optional)
# Schedules are not modeled in neither ESPHome nor Home Assistant.
#
# This parses the data point and emitting it as a string in the logs, and
# serves as an example for users desiring more advanced configurations.
on_datapoint_update:
- sensor_datapoint: 101
datapoint_type: raw
then:
- lambda: |-
// Apparently these vary per model; these are valid for the BHT-002
const int POS_HOUR = 1;
const int POS_MINUTE = 0;
const float TEMPERATURE_MULTIPLIER = 0.5f;
const std::map<int, std::string> DAY_OFFSET = {
{0, "days 1-5"},
{6, "day 6"},
{12, "day 7"},
};
for (auto& day : DAY_OFFSET) {
for (int period = 0; period < 6; period++) {
int offset = (day.first + period) * 3;
int hour = x[offset + POS_HOUR];
int minute = x[offset + POS_MINUTE];
float temp = x[offset + 2] * TEMPERATURE_MULTIPLIER;
ESP_LOGD("custom", "Scheduled program for %s %02d:%02d set at %.1f C", day.second.c_str(), hour, minute, temp);
}
}
climate:
- platform: tuya
name: "Thermostat"
switch_datapoint: 1
target_temperature_datapoint: 2
current_temperature_datapoint: 3
# eco_datapoint: 5
# eco_temperature: 20 °C
preset:
eco:
datapoint: 5
temperature: 20 °C
temperature_multiplier: 0.5
visual:
min_temperature: 5 °C
max_temperature: 35 °C
temperature_step: 0.5 °C
supports_heat: true
supports_cool: true
active_state:
datapoint: 102
cooling_value: 0
heating_value: 1
fanonly_value: 2
fan_mode:
datapoint: 103
auto_value: 0
high_value: 1
medium_value: 2
low_value: 3
sensor:
- platform: "tuya"
name: "Temperature"
sensor_datapoint: 3
unit_of_measurement: "°C"
device_class: "temperature"
accuracy_decimals: 1
filters:
- multiply: 0.5
# The climate component already includes temperature, but having the
# temperature as a separate sensor can be useful
disabled_by_default: true
# The external temperature sensor, if wired
- platform: "tuya"
name: "Temperature (external)"
sensor_datapoint: 102
unit_of_measurement: "°C"
device_class: "temperature"
accuracy_decimals: 1
filters:
- multiply: 0.5
disabled_by_default: true
switch:
- platform: "tuya"
name: "Lock"
icon: "mdi:lock"
switch_datapoint: 6
select:
- platform: "tuya"
name: "Scheduled programming"
icon: "mdi:calendar"
enum_datapoint: 4
options:
0: Use scheduled programs
1: Manual control
What seems to happen is that the device just has an HVAC mode, “heating” / “cooling” which is the mode the device is in. Shown with a sun and an ice-crystal on the display itself.
It seems the climate component mistakes the HVAC mode for the “heating” or “cooling” action, meaning that even though the temperature is set to 15C while the read temp is 20.5 it’s still in “heating” mode.
This doesn’t allow me to make further automation based on when the device goes from “idle” to “heating”.
Any idea what is wrong with this?