Last active
March 9, 2026 14:52
-
-
Save jamesj2/fd33118bdffd648583e6ddf7f59d57fb to your computer and use it in GitHub Desktop.
Inovelli & Motion: Smart Glow & Transitions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: "Inovelli & Motion: Smart Glow & Transitions 1.0" | |
| description: > | |
| Event-driven automation for Inovelli White switches (VTM31-SN) and Motion sensors (e.g., Ikea MYGGSPRAY). | |
| Features motion activation, day/night brightness levels, and a persistent glow | |
| that activates when the sun goes down or motion clears. Optionally force glow 24/7. | |
| Inovelli LED bar reflects current mode via select/number entities. | |
| domain: automation | |
| input: | |
| motion_entity: | |
| name: Motion Sensor | |
| description: The motion sensor to trigger the light. | |
| selector: | |
| entity: | |
| domain: binary_sensor | |
| device_class: occupancy | |
| light_entity: | |
| name: Light Entity | |
| description: The Inovelli dimmer switch to control. | |
| selector: | |
| entity: | |
| domain: light | |
| glow_entity: | |
| name: Night Glow Entity (Optional) | |
| description: > | |
| A separate light entity to use for Night Glow mode. | |
| If left empty, the main Light Entity will be used for glow as well. | |
| default: [] | |
| selector: | |
| entity: | |
| domain: light | |
| # -------------------------- | |
| # TIMING & THRESHOLDS | |
| # -------------------------- | |
| motion_wait_time: | |
| name: Motion Timeout | |
| description: Time in seconds to wait after motion clears before turning off (or glowing). | |
| default: 300 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 3600 | |
| unit_of_measurement: seconds | |
| manual_override_time: | |
| name: Manual Off Restore Time | |
| description: > | |
| If the light is turned off manually, how long (seconds) to wait before restoring Glow. | |
| Only applies when glow is active (night or force-glow-day). | |
| default: 25 | |
| selector: | |
| number: | |
| min: 5 | |
| max: 600 | |
| unit_of_measurement: seconds | |
| failsafe_time: | |
| name: Manual On Failsafe | |
| description: If turned on manually, turn off/glow after this many seconds of no interaction. | |
| default: 1800 | |
| selector: | |
| number: | |
| min: 60 | |
| max: 7200 | |
| unit_of_measurement: seconds | |
| sun_elevation: | |
| name: Sun Elevation Threshold | |
| description: The angle of the sun to consider "Dark" (e.g. -3.0). | |
| default: -3.0 | |
| selector: | |
| number: | |
| min: -90 | |
| max: 90 | |
| step: 0.5 | |
| mode: box | |
| # -------------------------- | |
| # BRIGHTNESS SETTINGS | |
| # -------------------------- | |
| bright_day: | |
| name: Day Brightness (Motion) | |
| default: 60 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: "%" | |
| bright_night: | |
| name: Night Brightness (Motion) | |
| default: 50 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: "%" | |
| bright_glow: | |
| name: Glow Brightness (Idle) | |
| default: 7 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: "%" | |
| # -------------------------- | |
| # FEATURE FLAGS | |
| # -------------------------- | |
| enable_glow: | |
| name: Enable Night Glow | |
| description: If disabled, the light will simply turn off at night instead of glowing. | |
| default: true | |
| selector: | |
| boolean: {} | |
| force_glow_day: | |
| name: Force Glow During Day | |
| description: If enabled, glow logic applies 24/7 regardless of sun elevation. | |
| default: false | |
| selector: | |
| boolean: {} | |
| # -------------------------- | |
| # TRANSITIONS | |
| # -------------------------- | |
| trans_standard: | |
| name: Standard Transition | |
| default: 1 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 10 | |
| unit_of_measurement: seconds | |
| trans_fade: | |
| name: Fade Transition (To Glow/Off) | |
| default: 10 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 30 | |
| unit_of_measurement: seconds | |
| trans_slow: | |
| name: Slow Transition (Sun Change) | |
| default: 15 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 60 | |
| unit_of_measurement: seconds | |
| # -------------------------- | |
| # LED CONTROL (Inovelli) | |
| # Leave all four blank to disable LED control. | |
| # -------------------------- | |
| led_color_entity: | |
| name: LED Color Entity | |
| description: "e.g. select.ceiling_light_led_color" | |
| default: [] | |
| selector: | |
| entity: | |
| domain: select | |
| led_effect_entity: | |
| name: LED Effect Entity | |
| description: "e.g. select.ceiling_light_led_effect" | |
| default: [] | |
| selector: | |
| entity: | |
| domain: select | |
| led_off_intensity_entity: | |
| name: LED Off Intensity Entity | |
| description: "Select entity controlling LED brightness when load is OFF (e.g. select.hall_bath_light_led_intensity_off)." | |
| default: [] | |
| selector: | |
| entity: | |
| domain: select | |
| led_on_intensity_entity: | |
| name: LED On Intensity Entity | |
| description: "Select entity controlling LED brightness when load is ON (e.g. select.hall_bath_light_led_intensity_on)." | |
| default: [] | |
| selector: | |
| entity: | |
| domain: select | |
| led_effect_active: | |
| name: LED Effect (Active States) | |
| description: Effect used for motion, glow, and manual states. | |
| default: "Solid" | |
| selector: | |
| select: | |
| options: | |
| - Solid | |
| - Fast Blink | |
| - Slow Blink | |
| - Middle Chase | |
| - Open Chase | |
| - Small To Big | |
| - Slow Falling | |
| - Middle Falling | |
| - Fast Falling | |
| - Slow Rising | |
| - Middle Rising | |
| - Fast Rising | |
| - Middle Blink | |
| - Slow Chase | |
| - Fast Chase | |
| - Slow Siren | |
| - Fast Siren | |
| led_motion_color: | |
| name: LED Color — Motion | |
| default: "Blue" | |
| selector: | |
| select: | |
| options: | |
| - Red | |
| - Orange | |
| - Lemon | |
| - Lime | |
| - Green | |
| - Teal | |
| - Cyan | |
| - Aqua | |
| - Blue | |
| - Violet | |
| - Magenta | |
| - Pink | |
| - White | |
| led_glow_color: | |
| name: LED Color — Glow | |
| default: "Orange" | |
| selector: | |
| select: | |
| options: | |
| - Red | |
| - Orange | |
| - Lemon | |
| - Lime | |
| - Green | |
| - Teal | |
| - Cyan | |
| - Aqua | |
| - Blue | |
| - Violet | |
| - Magenta | |
| - Pink | |
| - White | |
| led_manual_color: | |
| name: LED Color — Manual On | |
| default: "Green" | |
| selector: | |
| select: | |
| options: | |
| - Red | |
| - Orange | |
| - Lemon | |
| - Lime | |
| - Green | |
| - Teal | |
| - Cyan | |
| - Aqua | |
| - Blue | |
| - Violet | |
| - Magenta | |
| - Pink | |
| - White | |
| led_intensity_active: | |
| name: LED Intensity — Motion / Manual | |
| description: LED bar brightness for motion and manual states. | |
| default: "33" | |
| selector: | |
| select: | |
| options: | |
| - "0" | |
| - "1" | |
| - "3" | |
| - "5" | |
| - "8" | |
| - "10" | |
| - "13" | |
| - "16" | |
| - "20" | |
| - "23" | |
| - "26" | |
| - "30" | |
| - "33" | |
| - "36" | |
| - "40" | |
| - "45" | |
| - "50" | |
| - "60" | |
| - "70" | |
| - "80" | |
| - "90" | |
| - "100" | |
| led_intensity_glow: | |
| name: LED Intensity — Glow | |
| description: LED bar brightness for ambient glow state. | |
| default: "10" | |
| selector: | |
| select: | |
| options: | |
| - "0" | |
| - "1" | |
| - "3" | |
| - "5" | |
| - "8" | |
| - "10" | |
| - "13" | |
| - "16" | |
| - "20" | |
| - "23" | |
| - "26" | |
| - "30" | |
| - "33" | |
| - "36" | |
| - "40" | |
| - "45" | |
| - "50" | |
| - "60" | |
| - "70" | |
| - "80" | |
| - "90" | |
| - "100" | |
| mode: restart | |
| max_exceeded: silent | |
| trigger: | |
| # 1. Motion Detected | |
| - platform: state | |
| entity_id: !input motion_entity | |
| from: "off" | |
| to: "on" | |
| id: "motion_detected" | |
| # 2. Motion Cleared (Timeout) | |
| - platform: state | |
| entity_id: !input motion_entity | |
| to: "off" | |
| for: !input motion_wait_time | |
| id: "motion_timeout" | |
| # 3. Sun Elevation Drops (Dark) | |
| - platform: numeric_state | |
| entity_id: sun.sun | |
| attribute: elevation | |
| below: !input sun_elevation | |
| id: "elevation_dark" | |
| # 4. Sun Elevation Rises (Light) | |
| - platform: numeric_state | |
| entity_id: sun.sun | |
| attribute: elevation | |
| above: !input sun_elevation | |
| id: "elevation_light" | |
| # 5. Manual Off Restore | |
| - platform: state | |
| entity_id: !input light_entity | |
| to: "off" | |
| for: !input manual_override_time | |
| id: "manual_off_timer" | |
| # 6. Manual On LED Indicator | |
| # 1-second delay lets automation-triggered turn-ons (CASE 1) complete first. | |
| # context.parent_id check in CASE 6 ensures only physical presses get the green LED. | |
| - platform: state | |
| entity_id: !input light_entity | |
| to: "on" | |
| for: | |
| seconds: 1 | |
| id: "manual_light_on" | |
| # 7. Manual On Failsafe | |
| - platform: state | |
| entity_id: !input light_entity | |
| to: "on" | |
| for: !input failsafe_time | |
| id: "failsafe_timer" | |
| variables: | |
| # Inputs to Variables | |
| light_target: !input light_entity | |
| motion_target: !input motion_entity | |
| glow_entity_raw: !input glow_entity | |
| glow_target: "{{ glow_entity_raw if glow_entity_raw else light_target }}" | |
| threshold: !input sun_elevation | |
| use_glow: !input enable_glow | |
| force_day: !input force_glow_day | |
| # Brightness | |
| b_day: !input bright_day | |
| b_night: !input bright_night | |
| b_glow: !input bright_glow | |
| # Transitions | |
| t_std: !input trans_standard | |
| t_fade: !input trans_fade | |
| t_slow: !input trans_slow | |
| # Logic Checks | |
| current_elevation: "{{ state_attr('sun.sun', 'elevation') }}" | |
| is_actually_dark: "{{ current_elevation < threshold }}" | |
| is_dark: "{{ is_actually_dark or force_day }}" | |
| # LED Entities | |
| led_color_raw: !input led_color_entity | |
| led_effect_raw: !input led_effect_entity | |
| led_off_int_raw: !input led_off_intensity_entity | |
| led_on_int_raw: !input led_on_intensity_entity | |
| # has_led is true only when all four LED entities are configured | |
| has_led: "{{ led_color_raw != [] and led_effect_raw != [] and led_on_int_raw != [] and led_off_int_raw != [] }}" | |
| # LED Values | |
| led_effect: !input led_effect_active | |
| led_color_motion: !input led_motion_color | |
| led_color_glow: !input led_glow_color | |
| led_color_manual: !input led_manual_color | |
| led_int_active: !input led_intensity_active | |
| led_int_glow: !input led_intensity_glow | |
| action: | |
| - choose: | |
| # ------------------------------------------------------ | |
| # CASE 1: MOTION DETECTED | |
| # LED: motion color, active intensity | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "motion_detected" | |
| sequence: | |
| - choose: | |
| # Night/Dark Mode | |
| - conditions: "{{ is_actually_dark }}" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: !input light_entity | |
| data: | |
| brightness_pct: "{{ b_night }}" | |
| transition: "{{ t_std }}" | |
| # Day Mode | |
| default: | |
| - service: light.turn_on | |
| target: | |
| entity_id: !input light_entity | |
| data: | |
| brightness_pct: "{{ b_day }}" | |
| transition: "{{ t_std }}" | |
| # LED: Motion | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_color_raw }}" | |
| data: | |
| option: "{{ led_color_motion }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_effect_raw }}" | |
| data: | |
| option: "{{ led_effect }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_on_int_raw }}" | |
| data: | |
| option: "{{ led_int_active }}" | |
| # ------------------------------------------------------ | |
| # CASE 2: MOTION TIMEOUT | |
| # LED: glow color + glow intensity (both on and off) | |
| # or off-intensity reset to 1 when turning off | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "motion_timeout" | |
| # Ensure light is actually on before changing state | |
| - condition: state | |
| entity_id: !input light_entity | |
| state: "on" | |
| sequence: | |
| - choose: | |
| # Go to Glow | |
| - conditions: "{{ use_glow and is_dark }}" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ glow_target }}" | |
| data: | |
| brightness_pct: "{{ b_glow }}" | |
| transition: "{{ t_fade }}" | |
| # If using a separate glow entity, also turn off the main light | |
| - choose: | |
| - conditions: "{{ glow_target != light_target }}" | |
| sequence: | |
| - service: light.turn_off | |
| target: | |
| entity_id: "{{ light_target }}" | |
| data: | |
| transition: "{{ t_fade }}" | |
| # LED: Glow | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_color_raw }}" | |
| data: | |
| option: "{{ led_color_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_effect_raw }}" | |
| data: | |
| option: "{{ led_effect }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_on_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| # Turn Off — reset LED off-intensity to minimal | |
| default: | |
| - service: light.turn_off | |
| target: | |
| entity_id: !input light_entity | |
| data: | |
| transition: "{{ t_fade }}" | |
| # LED: Off (reset off-intensity so bar is nearly invisible) | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "1" | |
| # ------------------------------------------------------ | |
| # CASE 3: SUN DROPS (BECOMES DARK) | |
| # LED: glow color + glow intensity | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "elevation_dark" | |
| - condition: template | |
| value_template: "{{ use_glow }}" | |
| # Only activate glow if glow light is OFF and Motion is OFF | |
| - condition: template | |
| value_template: "{{ is_state(glow_target, 'off') }}" | |
| - condition: state | |
| entity_id: !input motion_entity | |
| state: "off" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ glow_target }}" | |
| data: | |
| brightness_pct: "{{ b_glow }}" | |
| transition: "{{ t_slow }}" | |
| # LED: Glow | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_color_raw }}" | |
| data: | |
| option: "{{ led_color_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_effect_raw }}" | |
| data: | |
| option: "{{ led_effect }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_on_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| # ------------------------------------------------------ | |
| # CASE 4: SUN RISES (BECOMES LIGHT) | |
| # LED: reset off-intensity to minimal | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "elevation_light" | |
| - condition: template | |
| value_template: "{{ not force_day }}" | |
| # Only turn off if glow light is ON (likely glowing) and no motion | |
| - condition: template | |
| value_template: "{{ is_state(glow_target, 'on') }}" | |
| - condition: state | |
| entity_id: !input motion_entity | |
| state: "off" | |
| sequence: | |
| - service: light.turn_off | |
| target: | |
| entity_id: "{{ glow_target }}" | |
| data: | |
| transition: "{{ t_slow }}" | |
| # LED: Off (reset off-intensity so bar is nearly invisible during day) | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "1" | |
| # ------------------------------------------------------ | |
| # CASE 5: MANUAL OFF RESTORE (Persistent Glow) | |
| # LED: glow color + glow intensity | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "manual_off_timer" | |
| - condition: template | |
| value_template: "{{ use_glow and is_dark }}" | |
| - condition: state | |
| entity_id: !input motion_entity | |
| state: "off" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ glow_target }}" | |
| data: | |
| brightness_pct: "{{ b_glow }}" | |
| transition: "{{ t_fade }}" | |
| # LED: Glow | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_color_raw }}" | |
| data: | |
| option: "{{ led_color_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_effect_raw }}" | |
| data: | |
| option: "{{ led_effect }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_on_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| # ------------------------------------------------------ | |
| # CASE 6: MANUAL ON (LED Indicator) | |
| # LED: manual color, active intensity | |
| # Skipped when automation triggered (context.parent_id is set) | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "manual_light_on" | |
| - condition: template | |
| value_template: "{{ trigger.to_state.context.parent_id is none }}" | |
| sequence: | |
| # LED: Manual | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_color_raw }}" | |
| data: | |
| option: "{{ led_color_manual }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_effect_raw }}" | |
| data: | |
| option: "{{ led_effect }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_on_int_raw }}" | |
| data: | |
| option: "{{ led_int_active }}" | |
| # ------------------------------------------------------ | |
| # CASE 7: FAILSAFE (Left on too long) | |
| # LED: glow color + glow intensity, or off-intensity reset | |
| # ------------------------------------------------------ | |
| - conditions: | |
| - condition: trigger | |
| id: "failsafe_timer" | |
| sequence: | |
| - choose: | |
| # Revert to Glow if Dark | |
| - conditions: "{{ use_glow and is_dark }}" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ glow_target }}" | |
| data: | |
| brightness_pct: "{{ b_glow }}" | |
| transition: "{{ t_fade }}" | |
| # If using a separate glow entity, also turn off the main light | |
| - choose: | |
| - conditions: "{{ glow_target != light_target }}" | |
| sequence: | |
| - service: light.turn_off | |
| target: | |
| entity_id: "{{ light_target }}" | |
| data: | |
| transition: "{{ t_fade }}" | |
| # LED: Glow | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_color_raw }}" | |
| data: | |
| option: "{{ led_color_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_effect_raw }}" | |
| data: | |
| option: "{{ led_effect }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_on_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "{{ led_int_glow }}" | |
| # Turn Off if Day — reset LED off-intensity to minimal | |
| default: | |
| - service: light.turn_off | |
| target: | |
| entity_id: !input light_entity | |
| data: | |
| transition: "{{ t_fade }}" | |
| # LED: Off (reset off-intensity) | |
| - if: "{{ has_led }}" | |
| then: | |
| - service: select.select_option | |
| target: | |
| entity_id: "{{ led_off_int_raw }}" | |
| data: | |
| option: "1" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment