diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..ca3ac46 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,44 @@ +name: Validate Blueprint + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + yamllint: + name: ๐Ÿš€ YAML Linting + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ“ฅ Checkout Code + uses: actions/checkout@v4 + + - name: ๐Ÿ Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: ๐Ÿ“ฆ Install yamllint + run: pip install yamllint + + - name: ๐ŸŽ›๏ธ Run yamllint + run: yamllint -f github -c .yamllint.yml . + + ha-config-check: + name: ๐Ÿ  Home Assistant Config Check + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ“ฅ Checkout Code + uses: actions/checkout@v4 + + - name: ๐Ÿ› ๏ธ Setup Mock HA Environment + run: | + mkdir -p config/blueprints/automation/my_blueprint + cp *.yaml config/blueprints/automation/my_blueprint/ + echo "default_config:" > config/configuration.yaml + + - name: ๐Ÿงช Test in Home Assistant Core + uses: frenck/action-home-assistant@v1 + with: + path: "config" diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..ee48d68 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,21 @@ +--- +extends: default + +rules: + # Disable cosmetic rules + document-start: disable + line-length: disable + comments: disable + comments-indentation: disable + trailing-spaces: disable + empty-lines: disable + truthy: disable + brackets: disable + + # Allow flexible sequence indentation + indentation: + spaces: 2 + indent-sequences: whatever + +ignore: | + .git/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc490bc --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# Change Light When Mode Changes + +[![Validate Blueprint](https://github.com/ticstyle/HA-Change-light-when-mode-changes/actions/workflows/validate.yml/badge.svg)](https://github.com/ticstyle/HA-Change-light-when-mode-changes/actions/workflows/validate.yml) + +A Home Assistant automation blueprint that dynamically adjusts light brightness levels and optional switches whenever your home's mode changes (`Morning`, `Day`, `Evening`, `Night`, `Away`). + +--- + +## ๐ŸŒŸ Features + +* **Mode-Driven Lighting:** Automatically sets predefined light brightness percentages matching your active day mode. +* **Optional Switch Control:** Easily enable/disable power switches or outlets alongside your lights for each mode. +* **Network Load Spreading:** Implements a randomized delay (5โ€“31 seconds) to distribute Zigbee/Z-Wave network traffic when running multiple automation instances simultaneously. +* **Away Mode Shutoff:** Automatically turns off targeted lights and switches when mode switches to **Away**. +* **Modern UI Sections:** Organized into collapsible UI configuration sections inside Home Assistant for a clean, intuitive setup. + +--- + +## ๐Ÿ“‹ Dependencies + +This blueprint relies on an entity tracking your active day modes (supporting states `Morning`, `Day`, `Evening`, `Night`, `Away`). + +* Recommended Integration: [Day Modes for Home Assistant](https://github.com/ticstyle/Day-Modes) (Available via HACS). +* *Alternative:* Any standard `input_select` or `sensor` entity returning matching state values. + +--- + +## ๐Ÿš€ Installation + +### Option 1: Direct Import via My Home Assistant +Click the button below to import the blueprint directly into your Home Assistant instance: + +[![Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Fticstyle%2FHA-Change-light-when-mode-changes%2Fblob%2Fmain%2Fchange_light_when_mode_changes.yaml) + +### Option 2: Manual Import +1. In Home Assistant, go to **Settings** > **Automations & Scenes** > **Blueprints**. +2. Click **Import Blueprint** in the bottom right corner. +3. Paste the blueprint URL: + ```text + [https://github.com/ticstyle/HA-Change-light-when-mode-changes/blob/main/change_light_when_mode_changes.yaml](https://github.com/ticstyle/HA-Change-light-when-mode-changes/blob/main/change_light_when_mode_changes.yaml) + ``` +4. Click **Preview** and then **Import**. + +--- + +## โš™๏ธ Configuration Inputs + +| Section | Input | Description | Default | +|---|---|---|---| +| **General** | `mode` | Sensor or input_select tracking day modes | `sensor.day_modes` | +| **General** | `light_target` | Target light entity, device, or area | `{}` | +| **General** | `control_switches` | Master toggle to enable switch/outlet control | `false` | +| **General** | `switch_target` | Target switch entity, device, or area | `{}` | +| **Morning** | `morning_toggle` | Enable processing for Morning mode | `true` | +| **Morning** | `morning_brightness` | Light brightness percentage (0โ€“100%) | `10%` | +| **Morning** | `morning_switch_on` | Turn switches ON or OFF during Morning | `true` | +| **Day** | `day_toggle` | Enable processing for Day mode | `true` | +| **Day** | `day_brightness` | Light brightness percentage (0โ€“100%) | `75%` | +| **Day** | `day_switch_on` | Turn switches ON or OFF during Day | `true` | +| **Evening** | `evening_toggle` | Enable processing for Evening mode | `true` | +| **Evening** | `evening_brightness` | Light brightness percentage (0โ€“100%) | `35%` | +| **Evening** | `evening_switch_on` | Turn switches ON or OFF during Evening | `true` | +| **Night** | `night_toggle` | Enable processing for Night mode | `true` | +| **Night** | `night_brightness` | Light brightness percentage (0โ€“100%) | `0%` | +| **Night** | `night_switch_on` | Turn switches ON or OFF during Night | `false` | +| **Away** | `away_toggle` | Enable processing for Away mode | `true` | +| **Away** | `away_switch_on` | Turn switches ON or OFF during Away | `false` | + +--- + +## ๐Ÿ“„ License + +This project is open-source and licensed under the [MIT License](LICENSE). diff --git a/change_light_when_mode_changes.yaml b/change_light_when_mode_changes.yaml index 53696b2..0dd1cce 100644 --- a/change_light_when_mode_changes.yaml +++ b/change_light_when_mode_changes.yaml @@ -1,37 +1,23 @@ blueprint: name: Change light when mode changes - description: - " ***Version*** - 1.2.0 - - ***What it does*** - Changes lights upon mode change, with a random delay of 5 to 31 seconds - to spread out the work load on the network if for example one would use this template - multiple times. - - When the mode is Away the enteties are automatically shut off. - The other modes are set for different times of the day if anyone is home. - - **Dependencies:** - * Built with a dependency on a sensor named `sensor.day_modes` which can have one of the following five values: `Away`, `Morning`, `Day`, `Eevening`, `Night`. - * A HACS integration for managing these modes can be found here: https://github.com/ticstyle/Day-Modes" - + description: >- + ### Version 1.3.0 + + Changes lights and optional switches upon day mode change, with a random delay of 5 to 31 seconds to spread out network traffic when using multiple instances. + + When the mode transitions to **Away**, entities are automatically turned off. Other modes adjust brightness and switch states based on your configured settings. + + #### Dependencies + * Requires a sensor tracking day modes (e.g., `sensor.day_modes`) with states: `Away`, `Morning`, `Day`, `Evening`, `Night`. + * A HACS integration for managing these modes can be found here: [Day Modes Integration](https://github.com/ticstyle/Day-Modes) + domain: automation source_url: https://github.com/ticstyle/HA-Change-light-when-mode-changes/blob/main/change_light_when_mode_changes.yaml input: - light_target: - name: Light(s) - default: {} - selector: - target: - entity: - - domain: - - light - mode: - name: Mode entity - description: Choose a sensor that is tracking the modes, alternatively an input_select helper that does the same. + name: Mode Entity + description: Select the sensor tracking day modes or an input_select helper. default: sensor.day_modes selector: entity: @@ -39,18 +25,26 @@ blueprint: - input_select - sensor - # ----------------------- - # Optional switch control - # ----------------------- + light_target: + name: Light Target + description: Select the target lights for this automation. + default: {} + selector: + target: + entity: + - domain: + - light + control_switches: - name: Control switches - description: Enable switch control in this automation (if you for example whant to control an outlet or a switch instead of a light). + name: Enable Switch Control + description: Enable to also control switches or outlets alongside your lights. default: false selector: boolean: {} switch_target: - name: Switch(es) + name: Switch Target + description: Select the target switches to control. default: {} selector: target: @@ -58,119 +52,154 @@ blueprint: - domain: - switch - morning_switch_on: - name: Morning โ€“ switches ON? - default: true - selector: - boolean: {} - - day_switch_on: - name: Day โ€“ switches ON? - default: true - selector: - boolean: {} - - evening_switch_on: - name: Evening โ€“ switches ON? - default: true - selector: - boolean: {} - - night_switch_on: - name: Night โ€“ switches ON? - default: false - selector: - boolean: {} - - away_switch_on: - name: Away โ€“ switches ON? - default: false - selector: - boolean: {} - # ----------------------- - # Lights (original) + # Morning Settings # ----------------------- - morning_toggle: - name: Use morning (effects both lights and switches) - selector: - boolean: {} - default: true + morning_section: + name: Morning Settings + icon: mdi:weather-sunset-up + input: + morning_toggle: + name: Enable Morning Mode + description: Control lights and switches when mode changes to Morning. + default: true + selector: + boolean: {} + + morning_brightness: + name: Morning Brightness + description: Brightness percentage (0-100%). + default: 10 + selector: + number: + min: 0.0 + max: 100.0 + step: 1.0 + mode: slider + + morning_switch_on: + name: Turn Switches ON in Morning + default: true + selector: + boolean: {} - morning_brightness: - name: Morning Brightness - description: 0-100%. - default: 10 - selector: - number: - min: 0.0 - max: 100.0 - step: 1.0 - mode: slider - - day_toggle: - name: Use day (effects both lights and switches) - selector: - boolean: {} - default: true + # ----------------------- + # Day Settings + # ----------------------- + day_section: + name: Day Settings + icon: mdi:weather-sunny + input: + day_toggle: + name: Enable Day Mode + description: Control lights and switches when mode changes to Day. + default: true + selector: + boolean: {} + + day_brightness: + name: Day Brightness + description: Brightness percentage (0-100%). + default: 75 + selector: + number: + min: 0.0 + max: 100.0 + step: 1.0 + mode: slider + + day_switch_on: + name: Turn Switches ON in Day + default: true + selector: + boolean: {} - day_brightness: - name: Day Brightness - description: 0-100%. - default: 75 - selector: - number: - min: 0.0 - max: 100.0 - step: 1.0 - mode: slider - - evening_toggle: - name: Use evening (effects both lights and switches) - selector: - boolean: {} - default: true + # ----------------------- + # Evening Settings + # ----------------------- + evening_section: + name: Evening Settings + icon: mdi:weather-sunset-down + input: + evening_toggle: + name: Enable Evening Mode + description: Control lights and switches when mode changes to Evening. + default: true + selector: + boolean: {} + + evening_brightness: + name: Evening Brightness + description: Brightness percentage (0-100%). + default: 35 + selector: + number: + min: 0.0 + max: 100.0 + step: 1.0 + mode: slider + + evening_switch_on: + name: Turn Switches ON in Evening + default: true + selector: + boolean: {} - evening_brightness: - name: Evening Brightness - description: 0-100%. - default: 35 - selector: - number: - min: 0.0 - max: 100.0 - step: 1.0 - mode: slider - - night_toggle: - name: Use night (effects both lights and switches) - selector: - boolean: {} - default: true + # ----------------------- + # Night Settings + # ----------------------- + night_section: + name: Night Settings + icon: mdi:weather-night + input: + night_toggle: + name: Enable Night Mode + description: Control lights and switches when mode changes to Night. + default: true + selector: + boolean: {} + + night_brightness: + name: Night Brightness + description: Brightness percentage (0-100%). + default: 0 + selector: + number: + min: 0.0 + max: 100.0 + step: 1.0 + mode: slider + + night_switch_on: + name: Turn Switches ON in Night + default: false + selector: + boolean: {} - night_brightness: - name: Night Brightness - description: 0-100%. - default: 0 - selector: - number: - min: 0.0 - max: 100.0 - step: 1.0 - mode: slider - - away_toggle: - name: Use away (effects both lights and switches) - selector: - boolean: {} - default: true + # ----------------------- + # Away Settings + # ----------------------- + away_section: + name: Away Settings + icon: mdi:home-export-outline + input: + away_toggle: + name: Enable Away Mode + description: Control lights and switches when mode changes to Away. + default: true + selector: + boolean: {} + + away_switch_on: + name: Turn Switches ON in Away + default: false + selector: + boolean: {} trigger: - - platform: state + - trigger: state entity_id: !input mode for: - hours: 0 - minutes: 0 seconds: 5 mode: restart @@ -179,10 +208,11 @@ max_exceeded: silent condition: [] action: - # The delay + # Random delay to prevent network load spikes when multiple instances trigger simultaneously - delay: - seconds: "{{ range(5, 31) | random | int }}" + seconds: "{{ range(5, 31) | random }}" + # Extract input configurations into local scope - variables: do_switches: !input control_switches sw_morning: !input morning_switch_on @@ -190,7 +220,6 @@ action: sw_evening: !input evening_switch_on sw_night: !input night_switch_on sw_away: !input away_switch_on - # Make the Use morning/day/evening/night/away toggles control whole sequences morning_enabled: !input morning_toggle day_enabled: !input day_toggle evening_enabled: !input evening_toggle @@ -198,157 +227,145 @@ action: away_enabled: !input away_toggle - choose: - - # Morning + # Morning Mode - conditions: - - condition: and - conditions: - - condition: state - entity_id: !input mode - state: ["Morning", "morning"] + - condition: state + entity_id: !input mode + state: + - "Morning" + - "morning" sequence: - condition: template value_template: "{{ morning_enabled }}" - - service: light.turn_on + - action: light.turn_on enabled: !input morning_toggle data: brightness_pct: !input morning_brightness target: !input light_target - # Switches (optional) - if: - condition: template value_template: "{{ do_switches }}" then: - - choose: - - conditions: - - condition: template - value_template: "{{ sw_morning }}" - sequence: - - service: switch.turn_on - target: !input switch_target - default: - - service: switch.turn_off + - if: + - condition: template + value_template: "{{ sw_morning }}" + then: + - action: switch.turn_on + target: !input switch_target + else: + - action: switch.turn_off target: !input switch_target - # Day + # Day Mode - conditions: - - condition: and - conditions: - - condition: state - entity_id: !input mode - state: ["Day", "day"] + - condition: state + entity_id: !input mode + state: + - "Day" + - "day" sequence: - condition: template value_template: "{{ day_enabled }}" - - service: light.turn_on + - action: light.turn_on enabled: !input day_toggle data: brightness_pct: !input day_brightness target: !input light_target - # Switches (optional) - if: - condition: template value_template: "{{ do_switches }}" then: - - choose: - - conditions: - - condition: template - value_template: "{{ sw_day }}" - sequence: - - service: switch.turn_on - target: !input switch_target - default: - - service: switch.turn_off + - if: + - condition: template + value_template: "{{ sw_day }}" + then: + - action: switch.turn_on + target: !input switch_target + else: + - action: switch.turn_off target: !input switch_target - # Evening + # Evening Mode - conditions: - - condition: and - conditions: - - condition: state - entity_id: !input mode - state: ["Evening", "evening"] + - condition: state + entity_id: !input mode + state: + - "Evening" + - "evening" sequence: - condition: template value_template: "{{ evening_enabled }}" - - service: light.turn_on + - action: light.turn_on enabled: !input evening_toggle data: brightness_pct: !input evening_brightness target: !input light_target - # Switches (optional) - if: - condition: template value_template: "{{ do_switches }}" then: - - choose: - - conditions: - - condition: template - value_template: "{{ sw_evening }}" - sequence: - - service: switch.turn_on - target: !input switch_target - default: - - service: switch.turn_off + - if: + - condition: template + value_template: "{{ sw_evening }}" + then: + - action: switch.turn_on + target: !input switch_target + else: + - action: switch.turn_off target: !input switch_target - # Night + # Night Mode - conditions: - - condition: and - conditions: - - condition: state - entity_id: !input mode - state: ["Night", "night"] + - condition: state + entity_id: !input mode + state: + - "Night" + - "night" sequence: - condition: template value_template: "{{ night_enabled }}" - - service: light.turn_on + - action: light.turn_on enabled: !input night_toggle data: brightness_pct: !input night_brightness target: !input light_target - # Switches (optional) - if: - condition: template value_template: "{{ do_switches }}" then: - - choose: - - conditions: - - condition: template - value_template: "{{ sw_night }}" - sequence: - - service: switch.turn_on - target: !input switch_target - default: - - service: switch.turn_off + - if: + - condition: template + value_template: "{{ sw_night }}" + then: + - action: switch.turn_on + target: !input switch_target + else: + - action: switch.turn_off target: !input switch_target - # Away + # Away Mode - conditions: - - condition: and - conditions: - - condition: state - entity_id: !input mode - state: ["Away", "away"] + - condition: state + entity_id: !input mode + state: + - "Away" + - "away" sequence: - condition: template value_template: "{{ away_enabled }}" - - service: light.turn_off - data: {} + - action: light.turn_off target: !input light_target enabled: !input away_toggle - # Switches (optional) - if: - condition: template value_template: "{{ do_switches }}" then: - - choose: - - conditions: - - condition: template - value_template: "{{ sw_away }}" - sequence: - - service: switch.turn_on - target: !input switch_target - default: - - service: switch.turn_off + - if: + - condition: template + value_template: "{{ sw_away }}" + then: + - action: switch.turn_on + target: !input switch_target + else: + - action: switch.turn_off target: !input switch_target