Hi,
Starting this thread to see if there are others out there trying to achieve similar things.
I need to control the temperature precisely using a heat pump that has an annoying logic for auto/temp control.
The idea is to use ESP Home PID controller and combine the following existing entities I have in Home Assistant.
I’m testing this in my office so the entities are all named office.
This is what gpt and I have got so far. Its doing funky shit like telling it to heat and cool at ther wrong time… dunno maybe I just need to dial it in.
remote_receiver:
pin:
number: GPIO32
inverted: true
dump: all
remote_transmitter:
pin: GPIO26
carrier_duty_percent: 50%
sensor:
- platform: homeassistant
id: esppoe_5_office_temperature
name: "Office Temperature"
entity_id: sensor.esppoe_5_office_temperature
globals:
- id: last_mode_change
type: int64_t
restore_value: no
initial_value: '0'
- id: mode_change_delay
type: int
restore_value: no
initial_value: '60000' # 1 minute in milliseconds
- id: last_mode
type: int
restore_value: yes
initial_value: '0' # 0 for OFF, 1 for COOL, 2 for HEAT
- id: last_target_temp
type: int
restore_value: yes
initial_value: '21'
output:
- platform: template
id: pid_output
type: float
write_action:
- lambda: |-
int64_t now = millis();
int new_mode;
int new_target_temp;
climate::ClimateFanMode new_fan_mode;
if (state > 0) {
// Cooling needed
new_mode = 1;
new_target_temp = std::max(16, std::min(30, static_cast<int>(round(21 - state * 5))));
} else {
// Heating needed
new_mode = 2;
new_target_temp = std::max(16, std::min(30, static_cast<int>(round(21 - state * 5))));
}
if (std::abs(state) > 0.8f) new_fan_mode = climate::CLIMATE_FAN_HIGH;
else if (std::abs(state) > 0.4f) new_fan_mode = climate::CLIMATE_FAN_MEDIUM;
else new_fan_mode = climate::CLIMATE_FAN_LOW;
bool change_needed = (new_mode != id(last_mode)) ||
(new_target_temp != id(last_target_temp)) ||
(new_fan_mode != id(office_ac).fan_mode);
if (change_needed && (now - id(last_mode_change) > id(mode_change_delay))) {
id(last_mode_change) = now;
id(last_mode) = new_mode;
id(last_target_temp) = new_target_temp;
auto call = id(office_ac).make_call();
call.set_mode(new_mode == 1 ? climate::CLIMATE_MODE_COOL : climate::CLIMATE_MODE_HEAT)
.set_target_temperature(new_target_temp)
.set_fan_mode(new_fan_mode)
.perform();
ESP_LOGD("PID", "Changed AC settings - Mode: %s, Temp: %d°C, Fan: %s",
(new_mode == 1 ? "COOL" : "HEAT"), new_target_temp,
(new_fan_mode == climate::CLIMATE_FAN_HIGH ? "HIGH" :
new_fan_mode == climate::CLIMATE_FAN_MEDIUM ? "MEDIUM" : "LOW"));
}
climate:
- platform: pid
id: pid_climate_controller
name: "PID Climate Controller"
sensor: esppoe_5_office_temperature
default_target_temperature: 21°C
cool_output: pid_output
heat_output: pid_output
control_parameters:
kp: 0.5
ki: 0.05
kd: 0.1
- platform: toshiba
id: office_ac
name: "Office AC"
sensor: esppoe_5_office_temperature
button:
- platform: template
name: "PID Climate Autotune"
on_press:
- climate.pid.autotune: pid_climate_controller