{ config, lib, namespace, ... }: with lib; let inherit (lib.${namespace}) mkBoolOpt; cfg = config.${namespace}.services.home-assistant.automation.voice-routines; # --------------------------------------------------------------------------- # BEDTIME ROUTINE # Triggers: "goodnight", "bedtime", "I'm going to sleep" # Actions: dim bedroom lights, set fan to sleep mode, # turn off other lights, TTS confirm on Voice satellite, # then turn off bedroom lights after 30s # --------------------------------------------------------------------------- bedtimeAutomation = '' - id: 'voice_bedtime_routine' alias: Voice - Bedtime Routine description: 'Triggered by voice: dim lights, set fan to sleep mode, turn off living room' triggers: - trigger: conversation command: - goodnight - good night - bedtime - time for bed - going to sleep - heading to bed conditions: [] actions: - parallel: - action: light.turn_on data: brightness_pct: 10 color_temp_kelvin: 2700 transition: 5 target: entity_id: light.bedroom_lights - action: light.turn_off data: transition: 3 target: entity_id: - light.living_room_lights - light.front_closet_lights - action: fan.set_preset_mode data: preset_mode: sleep target: entity_id: fan.bedroom_fan - action: fan.turn_on target: entity_id: fan.bedroom_air_purifier - delay: seconds: 3 - action: tts.speak data: cache: true message: >- Goodnight! Bedroom lights are dimmed, fan is in sleep mode, and all other lights are off. Sleep well. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper - delay: seconds: 30 - action: light.turn_off data: transition: 10 target: entity_id: light.bedroom_lights mode: single ''; # --------------------------------------------------------------------------- # GOOD MORNING ROUTINE # Triggers: "good morning", "wake up", "rise and shine" # Actions: gradually brighten bedroom lights to warm white, announce # weather + briefing via TTS on Voice satellite # --------------------------------------------------------------------------- morningAutomation = '' - id: 'voice_morning_routine' alias: Voice - Good Morning Routine description: 'Triggered by voice: brighten lights gradually and announce morning briefing' triggers: - trigger: conversation command: - good morning - good morning home - wake up - rise and shine - morning briefing - morning report conditions: [] actions: - action: light.turn_on data: brightness_pct: 40 color_temp_kelvin: 3000 transition: 10 target: entity_id: light.bedroom_lights - delay: seconds: 5 - action: light.turn_on data: brightness_pct: 80 color_temp_kelvin: 4000 transition: 15 target: entity_id: light.bedroom_lights - action: tts.speak data: cache: false message: >- Good morning! Today's weather is {{ states('weather.forecast_home') }}, with a temperature of {{ state_attr('weather.forecast_home', 'temperature') }} degrees. {% set lights_on = [ ('Living Room', states('light.living_room_lights')), ('Bedroom', states('light.bedroom_lights')), ('Front Closet', states('light.front_closet_lights')) ] | selectattr(1, 'eq', 'on') | map(attribute=0) | list %} {% if lights_on | length > 0 %} {{ lights_on | length }} lights left on. {% endif %} {% if states('vacuum.garbage_goober') == 'error' %} Garbage Goober needs attention. {% endif %} Have a great day! media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: restart ''; # --------------------------------------------------------------------------- # HOME STATUS SUMMARY # Triggers: "home status", "what's on", "status report" # --------------------------------------------------------------------------- homeStatusAutomation = '' - id: 'voice_home_status' alias: Voice - Home Status Summary description: 'Triggered by voice: announce active devices and any alerts' triggers: - trigger: conversation command: - home status - status report - house status - what is on - what is running conditions: [] actions: - action: tts.speak data: cache: false message: >- {% set lights_on = [ ('Living Room', states('light.living_room_lights')), ('Bedroom', states('light.bedroom_lights')), ('Front Closet', states('light.front_closet_lights')) ] | selectattr(1, 'eq', 'on') | map(attribute=0) | list %} {% if lights_on %} Lights on: {{ lights_on | join(', ') }}. {% else %} All lights are off. {% endif %} Bedroom fan is {{ states('fan.bedroom_fan') }}, preset {{ state_attr('fan.bedroom_fan', 'preset_mode') or 'unknown' }}. Living room purifier is {{ states('fan.living_room_air_purifier') }}, bedroom purifier is {{ states('fan.bedroom_air_purifier') }}. Garbage Goober is {{ states('vacuum.garbage_goober') }}. BedJet is {{ states('climate.bedjet_dbbf_c222') }}. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: restart ''; # --------------------------------------------------------------------------- # PET CARE - Manual feed Joey # --------------------------------------------------------------------------- feedJoeyAutomation = '' - id: 'voice_feed_joey' alias: Voice - Feed Joey description: 'Triggered by voice: dispense food for Joey' triggers: - trigger: conversation command: - feed Joey - give Joey food - Joey is hungry - Joey needs food - dispense food for Joey conditions: [] actions: - action: button.press target: entity_id: button.joey_smart_feeder_manual_feed - action: tts.speak data: cache: true message: Dispensing food for Joey now. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: single ''; # --------------------------------------------------------------------------- # PET CARE - Manual feed Luci # --------------------------------------------------------------------------- feedLuciAutomation = '' - id: 'voice_feed_luci' alias: Voice - Feed Luci description: 'Triggered by voice: dispense food for Luci' triggers: - trigger: conversation command: - feed Luci - give Luci food - Luci is hungry - Luci needs food - dispense food for Luci conditions: [] actions: - action: button.press target: entity_id: button.luci_smart_feeder_manual_feed - action: tts.speak data: cache: true message: Dispensing food for Luci now. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: single ''; # --------------------------------------------------------------------------- # PET CARE - Last fed status # --------------------------------------------------------------------------- petStatusAutomation = '' - id: 'voice_pet_status' alias: Voice - Pet Feeding Status description: 'Triggered by voice: announce when pets were last fed' triggers: - trigger: conversation command: - when was Joey last fed - when did Joey eat - has Joey been fed - when was Luci last fed - when did Luci eat - has Luci been fed - pet feeding status - when were the cats last fed - have the cats been fed conditions: [] actions: - action: tts.speak data: cache: false message: >- {% set joey_last = state_attr('automation.joey_s_scheduled_feeding', 'last_triggered') %} {% set luci_last = state_attr('automation.luci_s_scheduled_feeding', 'last_triggered') %} {% if joey_last %} Joey was last fed {{ relative_time(joey_last) }} ago. {% else %} I do not have a record of Joey last feeding. {% endif %} {% if luci_last %} Luci was last fed {{ relative_time(luci_last) }} ago. {% else %} I do not have a record of Luci last feeding. {% endif %} media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: restart ''; # --------------------------------------------------------------------------- # AIR QUALITY - Night mode: quiet purifiers at night (22:00) # --------------------------------------------------------------------------- airQualityNightAutomation = '' - id: 'air_quality_night_mode' alias: Air Quality - Night Mode description: 'At 10pm reduce air purifiers to low for quiet sleep' triggers: - trigger: time at: "22:00:00" conditions: - condition: state entity_id: fan.bedroom_air_purifier state: "on" actions: - action: fan.set_percentage data: percentage: 20 target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier mode: single ''; # --------------------------------------------------------------------------- # AIR QUALITY - Day mode: restore purifiers in morning (08:00) # --------------------------------------------------------------------------- airQualityDayAutomation = '' - id: 'air_quality_day_mode' alias: Air Quality - Day Mode description: 'At 8am restore air purifiers to normal operating speed' triggers: - trigger: time at: "08:00:00" conditions: - condition: state entity_id: fan.bedroom_air_purifier state: "on" actions: - action: fan.set_percentage data: percentage: 60 target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier mode: single ''; # --------------------------------------------------------------------------- # AIR QUALITY - Voice control # --------------------------------------------------------------------------- airQualityVoiceAutomation = '' - id: 'voice_air_quality' alias: Voice - Air Quality Control description: 'Voice commands to control air purifiers' triggers: - trigger: conversation command: - turn on air purifiers - start air purifiers - air purifiers on - turn off air purifiers - stop air purifiers - air purifiers off - air purifiers max - set air purifiers to max - air purifiers low - set air purifiers to low - quiet air purifiers - air quality status - how is the air quality - what is the air quality conditions: [] actions: - choose: - conditions: - condition: template value_template: >- {{ 'off' in trigger.sentence.lower() or 'stop' in trigger.sentence.lower() }} sequence: - action: fan.turn_off target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier - action: tts.speak data: cache: true message: Air purifiers turned off. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper - conditions: - condition: template value_template: >- {{ 'max' in trigger.sentence.lower() }} sequence: - action: fan.turn_on target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier - action: fan.set_percentage data: percentage: 100 target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier - action: tts.speak data: cache: true message: Air purifiers set to maximum. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper - conditions: - condition: template value_template: >- {{ 'low' in trigger.sentence.lower() or 'quiet' in trigger.sentence.lower() }} sequence: - action: fan.turn_on target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier - action: fan.set_percentage data: percentage: 20 target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier - action: tts.speak data: cache: true message: Air purifiers set to low. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper - conditions: - condition: template value_template: >- {{ 'status' in trigger.sentence.lower() or 'quality' in trigger.sentence.lower() }} sequence: - action: tts.speak data: cache: false message: >- Living room purifier is {{ states('fan.living_room_air_purifier') }} at {{ state_attr('fan.living_room_air_purifier', 'percentage') | int(default=0) }} percent. Bedroom purifier is {{ states('fan.bedroom_air_purifier') }} at {{ state_attr('fan.bedroom_air_purifier', 'percentage') | int(default=0) }} percent. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper default: - action: fan.turn_on target: entity_id: - fan.bedroom_air_purifier - fan.living_room_air_purifier - action: tts.speak data: cache: true message: Air purifiers are now on. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: restart ''; # --------------------------------------------------------------------------- # VACUUM - Voice control for Garbage Goober # --------------------------------------------------------------------------- vacuumVoiceAutomation = '' - id: 'voice_vacuum_control' alias: Voice - Vacuum Control description: 'Voice commands to start, stop, dock, and check Garbage Goober' triggers: - trigger: conversation command: - start vacuuming - start the vacuum - run the vacuum - vacuum the apartment - send out Garbage Goober - Garbage Goober go - clean the apartment - stop vacuuming - stop the vacuum - pause the vacuum - send the vacuum home - dock the vacuum - Garbage Goober return - vacuum status - where is the vacuum - how is Garbage Goober doing - what is Garbage Goober doing conditions: [] actions: - choose: - conditions: - condition: template value_template: >- {{ 'stop' in trigger.sentence.lower() or 'pause' in trigger.sentence.lower() }} sequence: - action: vacuum.stop target: entity_id: vacuum.garbage_goober - action: tts.speak data: cache: true message: Garbage Goober has been stopped. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper - conditions: - condition: template value_template: >- {{ 'dock' in trigger.sentence.lower() or 'home' in trigger.sentence.lower() or 'return' in trigger.sentence.lower() }} sequence: - action: vacuum.return_to_base target: entity_id: vacuum.garbage_goober - action: tts.speak data: cache: true message: Sending Garbage Goober back to its dock. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper - conditions: - condition: template value_template: >- {{ 'status' in trigger.sentence.lower() or 'where' in trigger.sentence.lower() or 'how' in trigger.sentence.lower() or 'what' in trigger.sentence.lower() }} sequence: - action: tts.speak data: cache: false message: >- Garbage Goober is currently {{ states('vacuum.garbage_goober') }}. {% set battery = state_attr('vacuum.garbage_goober', 'battery_level') %} {% if battery is not none %} Battery is at {{ battery }} percent. {% endif %} media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper default: - condition: state entity_id: vacuum.garbage_goober state: docked - action: vacuum.start target: entity_id: vacuum.garbage_goober - action: tts.speak data: cache: true message: Garbage Goober is starting to clean. media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: single ''; # --------------------------------------------------------------------------- # PRESENCE - Away mode when Matt leaves home # --------------------------------------------------------------------------- awayModeAutomation = '' - id: 'presence_away_mode' alias: Presence - Away Mode description: 'When Matt leaves: turn off all lights, dock vacuum if running' triggers: - trigger: state entity_id: person.matt_jallen from: home to: not_home for: minutes: 5 conditions: [] actions: - action: light.turn_off target: entity_id: - light.living_room_lights - light.bedroom_lights - light.front_closet_lights - if: - condition: not conditions: - condition: state entity_id: vacuum.garbage_goober state: docked then: - action: vacuum.return_to_base target: entity_id: vacuum.garbage_goober mode: single ''; # --------------------------------------------------------------------------- # PRESENCE - Welcome home # --------------------------------------------------------------------------- welcomeHomeAutomation = '' - id: 'presence_welcome_home' alias: Presence - Welcome Home description: 'When Matt arrives home: turn on living room lights, TTS welcome' triggers: - trigger: state entity_id: person.matt_jallen to: home from: not_home conditions: [] actions: - action: light.turn_on data: brightness_pct: 80 color_temp_kelvin: 3500 transition: 2 target: entity_id: light.living_room_lights - action: tts.speak data: cache: false message: >- Welcome home! The time is {{ now().strftime('%I:%M %p') }}. {% if states('vacuum.garbage_goober') not in ['docked', 'idle'] %} Garbage Goober is still {{ states('vacuum.garbage_goober') }}. {% endif %} media_player_entity_id: media_player.home_assistant_voice_09cf6a_media_player target: entity_id: tts.piper mode: single ''; voiceRoutineAutomations = concatStrings [ bedtimeAutomation morningAutomation homeStatusAutomation feedJoeyAutomation feedLuciAutomation petStatusAutomation airQualityNightAutomation airQualityDayAutomation airQualityVoiceAutomation vacuumVoiceAutomation awayModeAutomation welcomeHomeAutomation ]; in { options.${namespace}.services.home-assistant.automation.voice-routines = { enable = mkBoolOpt true "Enable voice routines and presence automations"; }; config = lib.mkIf (config.${namespace}.services.home-assistant.enable && cfg.enable) { environment.etc."hass/voice-routines.yaml" = { text = voiceRoutineAutomations; user = "hass"; group = "hass"; }; }; }