Hey David and welcome to the community
Respect for wiring this stuff for yourself! Bear in mind that Home Assistant can’t give you the stability a dedicated A/C controller might, but I guess you already know that
That’s quite a request, let’s see. You probably won’t need any python for this though, just YAML and jinja templates.
Okay, so from looking at your post title I’m guessing you’ve already set up a generic thermostat.
To make sure that the compressor doesn’t just switch on when HA sends a call for cooling without the fan running, I’d set up a Template Switch like this:
- platform: template
switches:
ac_compressor:
friendly_name: "A/C Compressor Switch"
value_template: "{{ is_state('switch.gpio_compressor', 'on') }}"
# switch.gpiocompressor should be the switch you use to switch the relay
turn_on:
service: script.compressor_on
turn_off:
service: script.compressor_off
This will be the switch that Home-Assistant will use to control the A/C. Of course we now need to add the scripts we linked:
compressor_on:
mode: single # Only allow one instance of this script to run
sequence:
- condition: state
entity_id: switch.gpio_compressor
state: off
# To make sure we don't screw up the state with the delay
- wait_delay: "{{ is_state('binary_sensor.compressor_cooldown', 'on') }}"
# Wait until the compressor has cooled down (If it already has it will continue immediately)
- service: switch.turn_on
data:
entity_id: fan.ac_fan
- delay:
seconds: 5
# 5 second delay you've asked for
- service: switch.turn_on
data:
entity_id: switch.gpio_compressor # Again, your GPIO switch for the compressor
compressor_off:
mode: single
sequence:
- wait_delay: "{{ is_state('script.compressor_on', 'off') }}"
# To make sure both scripts won't run at the same time
- service: switch.turn_off
data:
entity_id: switch.gpio_compressor
- delay:
minutes: 5
- service: switch.turn_off
data:
entity_id: fan.ac_fan
# To control the A/C fan, we set up this script that will be called from the fan integration.
ac_fan_on:
sequence:
- service: switch.turn_on
data_template: >-
{% if speed == "low" %}
switch.gpio1
{% elif speed == "med" %}
switch.gpio2
{% elif speed == "high" %}
switch.gpio3
{% endif %}
You will also need to add the template binary sensor, you can also add this one to the UI to see if the compressor is currently in cooldown:
binary_sensor:
- platform: template
sensors:
compressor_cooldown:
friendly_name: "Compressor in Cooldown"
value_template: "{% if as_timestamp(now()) - as_timestamp(state_attr('script.compressor_off', 'last_triggered')) > 300 and is_state('script.compressor_off', 'off') %} true {% endif %}"
# We both check the time the script has last executed as well as the current state
# to make sure we won't miss anything in case of a restart
I would also suggesst adding the fan as a Template fan. Have a read through it, I guess you won’t have a need for oscillation / direction.
fan:
- platform: template
fans:
ac_fan:
friendly_name: "A/C fan"
value_template: "{% if is_state('switch.gpiofan1', 'on') or is_state('switch.gpiofan2', 'on') or is_state('switch.gpiofan3', 'on') %} true {% endif %}"
speed_template: "{{ states('input_select.ac_fan_speed') }}"
turn_on:
service: script.ac_fan_on
data_template:
speed: "{{ states('input_select.ac_fan_speed') }}"
turn_off:
service: switch.turn_off
data:
entity_id: 'switch.gpio1, switch.gpio2, switch.gpio3'
set_speed:
service: script.ac_fan_on
data_template:
speed: "{{ speed }}"
speeds:
- 'low'
- 'med'
- 'high'
You also need the input_select for the fan speed:
input_select:
ac_fan_speed:
name: 'A/C Fan Speed'
options:
- low
- med
- high
As for the minimum cycle duration, have a look at the docs: Specify the parameter in your generic thermostat config.
To get the average of your temperature sensors, use the min/max sensor and set the type to mean:
sensor:
- platform: min_max
type: mean
name: "A/C temp sensor"
entity_ids:
- sensor.Room_1
- sensor.Room_2
- sensor.Room_3
- sensor.Input_air
Your generic thermostat could look like this. Please read the documentation for this integration and check every parameter.
climate:
- platform: generic_thermostat
name: 'My A/C'
heater: switch.ac_compressor
target_sensor: sensor.ac_temp_sensor
min_temp: 16
max_temp: 26
ac_mode: true
target_temp: 22
cold_tolerance: 0.3
hot_tolerance: 0
min_cycle_duration:
minutes: 5
initial_hvac_mode: "cool"
away_temp: 24
Those are just some ideas, check them out and report any issues with them, since I can’t test this config for myself