While I’m certainly not the first to notice this, I just wanted to share my experience recently using AI to finally assemble some of the complex automation ideas that have been floating around in my head but that I did not have the YAML or Jinga skills to create without significant homework and trial and error. I started with ChatGPT and moved to Claude-ai - which I think is better at it on the free level, because it doesn’t forget what you said 5 questions ago. I’m pretty comfortable with complex UI automations and scripts, but this has really opened up the power of templates, packages and sensors for me.
As with all things AI, they key is in how you talk to it, and I’ve learned a few helpful things that others may find useful. First, spend some time to write (and save) a very detailed and personalized prompt. The AI can actually help you develop that too if you ask it what it needs to know. Mine starts with: “I’m developing advanced home automation features and need assistance with device selection, automation logic, and code generation. Please help me establish the context for ongoing discussions about my smart home setup.” I then describe in broad detail my devices, hubs, brands, general approach to automation, existing services/automations, how I’ve structured my config.yaml file, and what my expectations are for generated code (my HA and hubitat versions, check against recent updates and changes, etc). I use this stock prompt to start every new conversation for a new project (since it tends to use up the free tokens for a given chat quickly). After that, it’s relatively easy to input the needs of the current project and get useful output with minimal need for correction and clarification.
I moved to this approach after some painful back and forth with chatGPT and numerous errors on my first attempt at using AI help.
This is far from having the AI think for you, since I found I needed to figure out very clearly spelled out asks in order to get something that works. I have used it to explore general ideas (like, what are the different approaches to integrate my 3 zone HVAC system into a home with lots of south facing windows, automated blinds, weather forecast services and in yard weather station in order to have my blinds and HVAC settings adjust automatically to account for current and anticipated weather conditions). However, once embarking on the details I’ve found it best to plan the overall final approach myself, so that I can follow the logic for troubleshooting and tweaking. I’ll then have the AI figure out how to work out many of the details by breaking it down into smaller, specific asks.
Some examples in my case:
I needed to extract hourly variables from my weather forecast service (like hourly temp, rainfall, conditions) to use in automation rules. In browsing the forums I knew it was possible, but that the code requirements had changed in the last couple years and there were a ton of threads with people working out the details of how to get it to work, with old broken code. I fed Claude my setup, the attributes of my weather service, told it the output sensors I wanted. It didn’t work initially. I then pointed it towards a few recent (very long) forum discussions on what was and wasn’t working recently and asked it to revise based on that information. Bam- fully functioning list of 2 dozen template sensors that worked after a copy and paste. Even if I figured out myself exactly how to do that with a lot of reading, it would have taken forever to write the code.
I’ve gotten better at the prompting, so I’ll share my most recent example that went very smoothly.
Here was my prompt:
That worked.
New project.
Using a similar approach in a new package, I would like to generate some template sensors that extract the current modes and setpoints on my Lennox thermostat. I will need a group of sensors for each of three zones. The data is currently available in 3 different thermostat devices (representing the 3 zones) in the Lennox integration. They are labeled:
system_2nd_floor
system_main_floor
system_basement
I would like to extract sensors for each zone that display the current setting for each of the attributes listed below. Beside each I have written the sample format of the output sensor to create. Modify the labels for each zone as appropriate:
hvac mode: lennox_mainfloor_system_mode
hvac action: lennox_mainfloor_action
Fan mode: lennox_mainfloor_fanmode
current fan state (on or off): lennox_mainfloor_fanstate
current preset mode: lennox_mainfloor_preset
target temp high: lennox_mainfloor_cool_below_setpoint
target temp low: lennox_mainfloor_heat_above_setpoint
Default to unavailable if data cannot be pulled.
For context, below is the sample attributes file as found in developer tools for the entity climate.system_main_floor
hvac_modes:
- "off"
- cool
- heat
- heat_cool
min_temp: 4.5
max_temp: 37
target_temp_step: 0.5
min_humidity: 15
max_humidity: 45
fan_modes:
- auto
- "on"
- circulate
preset_modes:
- schedule IQ
- summer
- winter
- spring/fall
- save energy
- away
- cancel hold
- cancel away mode
- schedule hold
- none
current_temperature: 22.5
target_temp_high: 22.5
target_temp_low: 19
current_humidity: 37
humidity: 20
fan_mode: circulate
hvac_action: idle
preset_mode: none
allergenDefender: false
damper: 0
demand: 0
fan: "off"
humidityMode: humidify
humOperation: "off"
tempOperation: "off"
ventilation: false
heatCoast: false
defrost: false
balancePoint: none
aux: false
coolCoast: false
ssr: false
zoneEnabled: true
zoningMode: zoned
friendly_name: System_main floor
supported_features: 158
10 seconds after hitting enter, it spit out a completely functional package I could copy and paste into my packages directory:
# Lennox Thermostat Sensors Package
# Extracts current modes and setpoints from Lennox thermostat integration
sensor:
# Main Floor Zone Sensors
- platform: template
sensors:
lennox_mainfloor_system_mode:
unique_id: lennox_mainfloor_system_mode_sensor
friendly_name: "Lennox Main Floor System Mode"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'hvac_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:thermostat
lennox_mainfloor_action:
unique_id: lennox_mainfloor_action_sensor
friendly_name: "Lennox Main Floor Action"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'hvac_action') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:thermostat-auto
lennox_mainfloor_fanmode:
unique_id: lennox_mainfloor_fanmode_sensor
friendly_name: "Lennox Main Floor Fan Mode"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'fan_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:fan
lennox_mainfloor_fanstate:
unique_id: lennox_mainfloor_fanstate_sensor
friendly_name: "Lennox Main Floor Fan State"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'fan') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:fan
lennox_mainfloor_preset:
unique_id: lennox_mainfloor_preset_sensor
friendly_name: "Lennox Main Floor Preset"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'preset_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:calendar-clock
lennox_mainfloor_cool_below_setpoint:
unique_id: lennox_mainfloor_cool_below_setpoint_sensor
friendly_name: "Lennox Main Floor Cool Below Setpoint"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'target_temp_high') }}
{% else %}
unavailable
{% endif %}
unit_of_measurement: "°C"
device_class: temperature
icon_template: mdi:thermometer-chevron-down
lennox_mainfloor_heat_above_setpoint:
unique_id: lennox_mainfloor_heat_above_setpoint_sensor
friendly_name: "Lennox Main Floor Heat Above Setpoint"
value_template: >
{% if states('climate.system_main_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_main_floor', 'target_temp_low') }}
{% else %}
unavailable
{% endif %}
unit_of_measurement: "°C"
device_class: temperature
icon_template: mdi:thermometer-chevron-up
# 2nd Floor Zone Sensors
lennox_2ndfloor_system_mode:
unique_id: lennox_2ndfloor_system_mode_sensor
friendly_name: "Lennox 2nd Floor System Mode"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'hvac_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:thermostat
lennox_2ndfloor_action:
unique_id: lennox_2ndfloor_action_sensor
friendly_name: "Lennox 2nd Floor Action"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'hvac_action') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:thermostat-auto
lennox_2ndfloor_fanmode:
unique_id: lennox_2ndfloor_fanmode_sensor
friendly_name: "Lennox 2nd Floor Fan Mode"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'fan_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:fan
lennox_2ndfloor_fanstate:
unique_id: lennox_2ndfloor_fanstate_sensor
friendly_name: "Lennox 2nd Floor Fan State"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'fan') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:fan
lennox_2ndfloor_preset:
unique_id: lennox_2ndfloor_preset_sensor
friendly_name: "Lennox 2nd Floor Preset"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'preset_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:calendar-clock
lennox_2ndfloor_cool_below_setpoint:
unique_id: lennox_2ndfloor_cool_below_setpoint_sensor
friendly_name: "Lennox 2nd Floor Cool Below Setpoint"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'target_temp_high') }}
{% else %}
unavailable
{% endif %}
unit_of_measurement: "°C"
device_class: temperature
icon_template: mdi:thermometer-chevron-down
lennox_2ndfloor_heat_above_setpoint:
unique_id: lennox_2ndfloor_heat_above_setpoint_sensor
friendly_name: "Lennox 2nd Floor Heat Above Setpoint"
value_template: >
{% if states('climate.system_2nd_floor') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_2nd_floor', 'target_temp_low') }}
{% else %}
unavailable
{% endif %}
unit_of_measurement: "°C"
device_class: temperature
icon_template: mdi:thermometer-chevron-up
# Basement Zone Sensors
lennox_basement_system_mode:
unique_id: lennox_basement_system_mode_sensor
friendly_name: "Lennox Basement System Mode"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'hvac_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:thermostat
lennox_basement_action:
unique_id: lennox_basement_action_sensor
friendly_name: "Lennox Basement Action"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'hvac_action') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:thermostat-auto
lennox_basement_fanmode:
unique_id: lennox_basement_fanmode_sensor
friendly_name: "Lennox Basement Fan Mode"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'fan_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:fan
lennox_basement_fanstate:
unique_id: lennox_basement_fanstate_sensor
friendly_name: "Lennox Basement Fan State"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'fan') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:fan
lennox_basement_preset:
unique_id: lennox_basement_preset_sensor
friendly_name: "Lennox Basement Preset"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'preset_mode') }}
{% else %}
unavailable
{% endif %}
icon_template: mdi:calendar-clock
lennox_basement_cool_below_setpoint:
unique_id: lennox_basement_cool_below_setpoint_sensor
friendly_name: "Lennox Basement Cool Below Setpoint"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'target_temp_high') }}
{% else %}
unavailable
{% endif %}
unit_of_measurement: "°C"
device_class: temperature
icon_template: mdi:thermometer-chevron-down
lennox_basement_heat_above_setpoint:
unique_id: lennox_basement_heat_above_setpoint_sensor
friendly_name: "Lennox Basement Heat Above Setpoint"
value_template: >
{% if states('climate.system_basement') not in ['unavailable', 'unknown'] %}
{{ state_attr('climate.system_basement', 'target_temp_low') }}
{% else %}
unavailable
{% endif %}
unit_of_measurement: "°C"
device_class: temperature
icon_template: mdi:thermometer-chevron-up
I’ve really been enjoying this process and excited about what it opens up. By reading what is generated (and yes at times doing a lot of error troubleshooting with the AI), I feel I’m also getting a much better grasp of using the code myself, and finding where problems might lie. It is definitely a faster way to code, but you still need to put in the mental effort and time upfront to frame exactly what you need, and your own smart home context to make it work in.
Overall I’m a bit of a skeptic about AI hype, but I watched a few videos about how to use it and how not to use it, and applying those principles has made a huge difference in getting my complex automations off the ground. Hope someone else finds this helpful!