Compare commits

..

28 Commits

Author SHA1 Message Date
4b285770d2 Fix presence_mode_reset blueprint variable scoping issue
Move condition check into action sequence after variables are defined.
Previously, the condition tried to use 'occupancy_sensors' before it was
defined, causing UndefinedError during automation execution.
2025-12-21 15:35:23 -08:00
a5a6b9d4b6 Add comprehensive documentation and testing tools
- Update README with complete setup guide and all blueprint URLs
- Add PACKAGE_SETUP_GUIDE with step-by-step setup instructions
- Add ROOM_CONFIGURATION_GUIDE with bedroom, living room, and bathroom examples
- Add HARDWARE_TESTING_CHECKLIST for validating with real Inovelli switches
- Add CHANGELOG documenting v1.0.0 release
- Add validation script for automated YAML testing
- Add test configuration example for testing without hardware
2025-12-21 14:30:53 -08:00
5eec41a43c Add button actions and presence reset blueprints
- Add inovelli_button_actions blueprint for multi-tap controls
  - Double-tap up: brightness boost (+50%)
  - Double-tap down: return to adaptive lighting
  - Triple-tap up: max brightness (100%, 4000K)
  - Triple-tap down: night light (5%, warm red)
  - Configurable auto-reset timeout

- Add presence_mode_reset blueprint for occupancy integration
  - Auto-reset manual control when room empty
  - Optional mode reset to default
  - Configurable empty delay
  - Multiple occupancy sensor support

- Fix entity name in living room template (light.living_room_lights)
2025-12-21 14:30:41 -08:00
602a2b7e78 Phase 2 2025-12-20 15:36:06 -08:00
27d322f09f Update feedback flash to 0.5 seconds 2025-12-20 15:33:41 -08:00
4f344e7b16 Fix inovelli_mode_cycling blueprint trigger for event entities
Correct the trigger mechanism to match how Home Assistant event entities
actually work. Event entities trigger on state changes and expose the
actual event type as an attribute, not as event_data.

Changes:
- Replace platform:event trigger with platform:state
- Add condition to check event_type attribute for 'config_single'
- Remove incorrect event_data and state_changed event_type usage

This matches the working pattern used in production automations and
ensures the blueprint triggers correctly when the config button is
pressed on Inovelli switches.
2025-12-20 15:24:24 -08:00
44c7771f09 Update inovelli_mode_cycling blueprint to use event entity
Change from sensor-based to event-based trigger for Inovelli button
presses. This aligns with Zigbee2MQTT's modern event entity approach
and matches the Phase 1 plan specification.

Changes:
- Replace switch_action_sensor (sensor domain) with switch_action_event (event domain)
- Update trigger from platform:state to platform:event with event_data
- Use state_changed event type for proper event handling

This provides more reliable button press detection and cleaner event
handling compared to the older sensor state monitoring approach.
2025-12-20 15:15:03 -08:00
988a7e0933 Fix inovelli_mode_cycling blueprint: remove invalid 'example' key
The 'example' key is not a valid blueprint input parameter in Home Assistant.
Moved the example value into the description field instead.
2025-12-20 15:02:37 -08:00
258c4172e9 Implement Adaptive Lighting Mode System Phase 1 foundation
Add global mode definitions and config button mode cycling blueprint to
establish the foundation for the adaptive lighting mode system.

Changes:
- Add input_text helpers for all 11 mode settings (Adaptive, Reading,
  Relaxing, Sleep, Theater, Party, Homework, Play, Cooking, Dining,
  Cleanup) with JSON configuration for brightness, color temp, and
  transition parameters
- Store mode settings as individual input_text entities to work within
  Home Assistant's 255 character limit
- Add usage notes for accessing mode settings in templates
- Fix variable definition bug in inovelli_mode_cycling blueprint by
  adding zigbee2mqtt_device_name to variables section
- Update README to reflect that PACKAGE_SETUP_GUIDE.md exists

All YAML files validated with yamllint. JSON configuration validated
with jq.

Part of Phase 1 implementation from adaptive lighting mode system plan.
Automated verification complete, ready for manual testing.
2025-12-20 15:00:02 -08:00
ea20e11bdd Remove invalid helper script from global package
- Remove script.get_mode_color which had incorrect response syntax
- Replace with usage notes showing how to access mode colors in templates
- Blueprints and automations access colors directly via templates
- Fixes 'extra keys not allowed @ data['sequence'][0]['response']' error
2025-12-20 14:41:53 -08:00
ea426e56ef Fix input_text max length constraint for mode colors
- Add max: 255 parameter to adaptive_lighting_mode_colors input_text
- Minify JSON to fit within Home Assistant's 100 character default limit
- Remove adaptive_lighting_mode_settings input_text (too long, convert to comments)
- Remove get_mode_settings script (no longer needed)
- Fix template syntax: use states() instead of state_attr() for input_text values
- Convert mode settings to reference documentation comments

This fixes the 'Initial value length not in range 0-100' error from Home Assistant.
2025-12-20 14:38:21 -08:00
2cb34c7c9f Add Adaptive Lighting Mode System foundation (Phase 1)
Implement the foundation for a comprehensive mode-based lighting control
system for Inovelli Blue Dimmer Switches with Adaptive Lighting integration.

This Phase 1 implementation includes:

- Global mode definitions package (packages/adaptive_lighting_global.yaml)
  containing ROYGBIV color scheme mappings and mode settings for all
  standard modes (Adaptive, Reading, Theater, Sleep, etc.)

- Inovelli mode cycling blueprint (blueprints/automation/inovelli_mode_cycling.yaml)
  enabling config button to cycle through lighting modes with LED feedback

- Updated README with system overview, features, and quick start guide

The system provides room-specific lighting modes with visual LED feedback,
config button control, and git-trackable configuration via Home Assistant
packages.

Next phases will add mode application automations, button action blueprints,
presence integration, and comprehensive documentation.
2025-12-20 14:22:24 -08:00
c9529ed52b Clarify that Adaptive Lighting integration is optional
Update blueprint and README to make it clear that the Adaptive Lighting
switch can be left empty, in which case lights will use simple on/off
control. Add clarifications to input descriptions and enhance
documentation with better examples.
2025-12-06 14:49:03 -08:00
621fdeb709 Only apply adaptive lighting when switch is on
Fixes #1
2025-11-15 12:20:03 -08:00
f301d1b5e2 Switch mode to restart 2001-01-01 00:00:00 +00:00
5d18dbc336 Fix template variable access in actions
Adds variables section to properly expose blueprint inputs as template variables, fixing undefined variable errors in conditions.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:52:40 -08:00
d338a7298a Revert to simple multiple entity selector
Simplifies sensor selection back to multiple entity selector instead of complex target/area approach. More reliable and straightforward while still supporting multiple sensors.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:41:10 -08:00
b612412470 Fix trigger to use event-based state monitoring
Replaces unsupported domain/device_class trigger with event-based approach that listens to state_changed events and filters for selected occupancy sensors.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:25:58 -08:00
cfddf9145d Fix adaptive lighting switch validation
Adds check for empty dict to prevent entity_id errors when adaptive lighting switch is not configured.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:24:38 -08:00
89d268b3f4 Fix trigger to use domain-based filtering
Replaces template variable in trigger entity_id with domain/device_class trigger and condition filter. This properly handles dynamic sensor selection from target selector.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:23:24 -08:00
a7d475c1c5 Fix trigger syntax for area-based sensor selection
Replaces invalid 'target' key in trigger with proper 'entity_id' using variables section to resolve target selector. Simplifies template logic by centralizing sensor resolution.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:21:58 -08:00
d03b80a211 Support area-based motion sensor selection
Updates occupancy controlled lights to use target selector like lights, allowing selection of entire areas of motion sensors. Lights turn on when any sensor in the selected areas/entities detects motion and turn off when all are clear for the delay period.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:20:11 -08:00
b894471828 Add configurable off delay to occupancy controlled lights
Adds off_delay input parameter allowing users to configure how long to wait after motion stops before turning lights off. Includes re-verification to prevent lights turning off if motion resumes during the delay period.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:14:02 -08:00
9e4de90676 Add occupancy controlled lights 2025-10-27 14:55:37 -07:00
d5034210ed Try using an external counter 2025-10-25 22:23:04 -07:00
3f82719fa4 New format with mode:single 2025-10-25 22:09:16 -07:00
86f3d9e0e1 New architecture attempt 2025-10-25 22:07:05 -07:00
f392cea7de Set mode to single 2025-10-25 21:56:52 -07:00
16 changed files with 1890 additions and 24 deletions

53
CHANGELOG.md Normal file
View File

@@ -0,0 +1,53 @@
# Changelog
All notable changes to the Adaptive Lighting Mode System will be documented in
this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [1.0.0] - 2025-12-20
### Added
**Blueprints**:
- `inovelli_mode_cycling.yaml` - Config button cycles through lighting modes
with LED feedback
- `inovelli_button_actions.yaml` - Multi-tap brightness controls with
auto-reset
- `presence_mode_reset.yaml` - Auto-reset modes and manual control when room
empty
**Package Templates**:
- `adaptive_lighting_global.yaml` - Shared mode definitions and color mappings
- `adaptive_lighting_bedroom_template.yaml` - Complete bedroom example with 5
modes
- `adaptive_lighting_living_room_template.yaml` - Living room example with
entertainment modes
- `adaptive_lighting_simple_template.yaml` - Minimal template for simple rooms
**Documentation**:
- `PACKAGE_SETUP_GUIDE.md` - Setup instructions and version control guide
- `ROOM_CONFIGURATION_GUIDE.md` - Room-by-room configuration examples
- `HARDWARE_TESTING_CHECKLIST.md` - Comprehensive testing checklist
- Updated `README.md` with system overview and quick start
**Features**:
- Room-specific mode definitions (Adaptive, Reading, Theater, Sleep, etc.)
- Visual LED feedback using ROYGBIV color scheme
- Weekend mode with automatic sunrise/sunset adjustments
- Multi-tap button actions (boost, max, night light)
- Presence-based auto-reset
- Version-controlled package-based configuration
### Technical Details
- Zigbee2MQTT integration for Inovelli Blue VZM31-SN switches
- Home Assistant Adaptive Lighting integration required
- Package-based architecture for easy version control
- Template-driven room setup for scalability
### Known Limitations
- Zigbee2MQTT only (Z-Wave JS requires different MQTT topics)
- Settings from `adaptive_lighting.change_switch_settings` reset on HA restart
- Requires manual Inovelli switch configuration (Smart Bulb Mode, buttonDelay)

View File

@@ -0,0 +1,110 @@
# Hardware Testing Checklist
## Prerequisites
- [ ] Inovelli Blue Dimmer VZM31-SN paired with Zigbee2MQTT
- [ ] Switch in Smart Bulb Mode (select.xxx_smart_bulb_mode = "Smart Bulb
Mode")
- [ ] buttonDelay set to 500ms or 700ms (select.xxx_button_delay)
- [ ] Smart bulbs powered and responsive
- [ ] Adaptive Lighting integration installed and configured
- [ ] All packages and blueprints loaded
## Switch Configuration Tests
- [ ] Smart Bulb Mode enabled: Load always powered
- [ ] LED bar displays color correctly
- [ ] LED intensity acceptable (adjust if too bright/dim)
- [ ] Button presses detected: event.xxx_action updates
- [ ] Single tap: Shows "up_single" or "down_single"
- [ ] Double tap: Shows "up_double" or "down_double" reliably
- [ ] Triple tap: Shows "up_triple" or "down_triple" reliably
- [ ] Config button: Shows "config_single"
## Mode Cycling Tests
- [ ] Config button press triggers automation
- [ ] Mode cycles through all available modes
- [ ] Mode cycles back to first after last mode
- [ ] input_select updates in UI
- [ ] LED color changes to match mode
- [ ] LED flash pulse visible (3 seconds)
- [ ] Colors distinguishable for each mode
- [ ] Cycle works from any starting mode
## Mode Application Tests
For each mode:
- [ ] Adaptive: AL settings reset to configuration defaults
- [ ] Reading: Brightness increases, color cools
- [ ] Theater: Brightness decreases, color warms
- [ ] Sleep: Very dim, red/amber color
- [ ] Manual Override: AL paused, manual control enabled
## Button Action Tests
- [ ] Double tap up: Brightness boosts +50%
- [ ] Double tap up: Color temperature increases +1000K
- [ ] Double tap down: Returns to AL control immediately
- [ ] Triple tap up: Sets 100% brightness, 4000K (neutral)
- [ ] Triple tap down: Sets 5% brightness, warm red
- [ ] Auto-reset: Returns to AL after configured timeout
- [ ] Auto-reset: Works after boost action
- [ ] Auto-reset: Works after max brightness
- [ ] Auto-reset: Works after night light
## Weekend Mode Tests (if configured)
- [ ] Enables automatically Friday 10pm
- [ ] Disables automatically Sunday 10pm
- [ ] Sunrise time shifts when enabled
- [ ] Max brightness reduces when enabled
- [ ] Settings restore when disabled
- [ ] Triple-tap toggle works (if configured)
- [ ] LED flash confirms toggle
## Presence Integration Tests (if configured)
- [ ] Presence sensor triggers correctly
- [ ] Lights turn on when occupied
- [ ] Lights stay on while occupied
- [ ] Manual control resets after room empty
- [ ] Mode resets after room empty (if configured)
- [ ] Delay timing is appropriate
- [ ] Works with multiple sensors (OR logic)
## Edge Cases and Failure Modes
- [ ] Rapid button presses don't cause errors
- [ ] Mode change while lights off doesn't error
- [ ] Switching modes rapidly doesn't break AL
- [ ] Zigbee network congestion doesn't cause issues
- [ ] Home Assistant restart preserves mode
- [ ] AL switch off doesn't break mode system
- [ ] Invalid mode name doesn't crash automation
- [ ] Missing entity gracefully fails
## Performance Tests
- [ ] Mode change response < 1 second
- [ ] LED update response < 1 second
- [ ] Button action response < 1 second
- [ ] AL adaptation smooth (no flicker)
- [ ] No automation trace errors
- [ ] No excessive log warnings
## Multi-Room Tests
- [ ] Multiple rooms work independently
- [ ] Mode cycling doesn't affect other rooms
- [ ] LED colors consistent across rooms
- [ ] Performance acceptable with many rooms
- [ ] Global package shared correctly
## Documentation Accuracy
- [ ] All entity IDs in examples are correct format
- [ ] Zigbee2MQTT topics match actual topics
- [ ] Service calls work as documented
- [ ] Examples produce expected behavior
- [ ] Troubleshooting guide solves real issues

220
PACKAGE_SETUP_GUIDE.md Normal file
View File

@@ -0,0 +1,220 @@
# Package Setup Guide
## Overview
This guide explains how to set up Home Assistant packages for the Adaptive
Lighting Mode System and configure version control.
## What Are Packages?
Packages allow you to organize Home Assistant configuration into multiple YAML
files instead of one giant `configuration.yaml`. Each package file can contain
automations, helpers, scripts, and other entities related to a specific feature
or room.
**Benefits**:
- Organize configuration by room or feature
- Version control specific areas independently
- Easier to share and reuse configurations
- Keep `configuration.yaml` clean and minimal
## Prerequisites
- Home Assistant installed and running
- SSH or file editor access to your HA configuration directory
- Git installed (optional, for version control)
- Adaptive Lighting integration installed via HACS
## Step 1: Enable Packages in Home Assistant
**1.1 Edit your `configuration.yaml`**
Add this line to the top of your `configuration.yaml`:
```yaml
homeassistant:
packages: !include_dir_named packages/
```
**1.2 Create the packages directory**
SSH into your Home Assistant instance or use File Editor add-on:
```bash
cd /config
mkdir packages
```
**1.3 Restart Home Assistant**
Settings → System → Restart Home Assistant
## Step 2: Install Global Definitions
**2.1 Copy the global package**
Download or copy `packages/adaptive_lighting_global.yaml` from this repository
to your `/config/packages/` directory.
**2.2 Reload YAML configuration**
Developer Tools → YAML → Reload all YAML configuration
**2.3 Verify helpers exist**
Settings → Devices & Services → Helpers
You should see:
- `input_text.adaptive_lighting_mode_colors`
- `input_text.adaptive_lighting_settings_adaptive`
- `input_text.adaptive_lighting_settings_reading`
- `input_text.adaptive_lighting_settings_relaxing`
- `input_text.adaptive_lighting_settings_sleep`
- And several more mode settings helpers
## Step 3: Import Blueprints
**3.1 Import via UI**
Settings → Automations & Scenes → Blueprints → Import Blueprint
Import these URLs:
```
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/blueprints/automation/inovelli_mode_cycling.yaml
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/blueprints/automation/inovelli_button_actions.yaml
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/blueprints/automation/presence_mode_reset.yaml
```
**3.2 Verify blueprints imported**
Settings → Automations & Scenes → Blueprints
You should see all three blueprints listed.
## Step 4: Configure Your First Room
**4.1 Choose a template**
Select the appropriate template for your room type:
- Bedroom: `packages/adaptive_lighting_bedroom_template.yaml`
- Living room: `packages/adaptive_lighting_living_room_template.yaml`
- Simple (bathroom, closet): `packages/adaptive_lighting_simple_template.yaml`
**4.2 Copy and customize**
```bash
cd /config/packages
cp adaptive_lighting_bedroom_template.yaml adaptive_lighting_master_bedroom.yaml
```
Edit the file and update:
- Replace "bedroom" with "master_bedroom" throughout
- Update entity IDs (search for # UPDATE THIS comments)
- Adjust available modes if desired
- Customize mode settings
**4.3 Reload configuration**
Developer Tools → YAML → Reload all YAML configuration
**4.4 Create blueprint automations**
Settings → Automations & Scenes → Create Automation → Use Blueprint
Create automations for:
1. Inovelli Mode Cycling (config button)
2. Inovelli Button Actions (multi-tap)
3. Presence Mode Reset (if you have occupancy sensors)
## Step 5: Version Control Setup (Optional)
**5.1 Initialize git repository**
```bash
cd /config
git init
```
**5.2 Create .gitignore**
```bash
cat > .gitignore << 'EOF'
# Secrets and sensitive data
secrets.yaml
*.db
*.db-shm
*.db-wal
*.log
# Generated files
*.pyc
__pycache__/
.storage/
.cloud/
.google.token
# Add-on data
.ssh/
.vscode/
# Keep these version controlled:
# - packages/
# - automations.yaml
# - configuration.yaml
# - blueprints/
EOF
```
**5.3 Commit initial setup**
```bash
git add packages/ automations.yaml configuration.yaml
git commit -m "Initial adaptive lighting mode system setup"
```
**5.4 Add remote (optional)**
```bash
git remote add origin your-git-repo-url
git push -u origin main
```
## Troubleshooting
### Packages not loading
**Symptom**: Helpers don't appear after reloading
**Solutions**:
- Check `configuration.yaml` has packages line
- Verify packages directory exists at `/config/packages/`
- Check YAML syntax: `yamllint /config/packages/*.yaml`
- Look for errors in Settings → System → Logs
### Entity IDs don't match
**Symptom**: Automations fail because entities not found
**Solutions**:
- Go to Settings → Devices & Services → MQTT
- Find your Inovelli switch device
- Note the exact entity IDs (event.xxx_action,
number.xxx_led_color_when_on)
- Update package file with correct entity IDs
- Reload YAML
### Blueprints not working
**Symptom**: Automation from blueprint doesn't trigger
**Solutions**:
- Check automation trace: Settings → Automations → [your automation] →
Traces
- Verify trigger entity is correct
- Ensure Inovelli buttonDelay is set to >= 500ms
- Test button press in Developer Tools → States (watch event.xxx_action)
## Next Steps
See [ROOM_CONFIGURATION_GUIDE.md](ROOM_CONFIGURATION_GUIDE.md) for detailed
room setup examples.

175
README.md
View File

@@ -1,5 +1,180 @@
# Home Assistant Blueprints # Home Assistant Blueprints
## Adaptive Lighting Mode System
A comprehensive mode-based lighting control system for Inovelli Blue Dimmer
Switches with Adaptive Lighting integration.
### Features
- **Room-specific modes**: Define custom lighting modes per room (Reading,
Theater, Sleep, etc.)
- **Visual LED feedback**: LED bar color indicates current mode
- **Config button control**: Press config button to cycle through modes
- **Multi-tap actions**: Double-tap boost, triple-tap max/night light
- **Adaptive Lighting integration**: Dynamic brightness and color following sun
position
- **Version controlled**: All configuration in git-trackable package files
### System Components
**Blueprints** (Reusable):
- `inovelli_mode_cycling.yaml` - Config button cycles modes with LED feedback
- `inovelli_button_actions.yaml` - Multi-tap brightness controls
- `presence_mode_reset.yaml` - Auto-reset on room exit
**Packages** (Templates):
- `adaptive_lighting_global.yaml` - Shared mode definitions and colors
- `adaptive_lighting_bedroom_template.yaml` - Complete bedroom example
- `adaptive_lighting_living_room_template.yaml` - Living room example
- `adaptive_lighting_simple_template.yaml` - Minimal single-mode room
### Setup Guide
**Quick Start**:
1. Install Adaptive Lighting integration via HACS
2. Follow [PACKAGE_SETUP_GUIDE.md](PACKAGE_SETUP_GUIDE.md) to enable packages
3. Copy templates from `packages/` directory
4. Import blueprints via UI
5. See [ROOM_CONFIGURATION_GUIDE.md](ROOM_CONFIGURATION_GUIDE.md) for examples
**Documentation**:
- [PACKAGE_SETUP_GUIDE.md](PACKAGE_SETUP_GUIDE.md) - Initial setup and version
control
- [ROOM_CONFIGURATION_GUIDE.md](ROOM_CONFIGURATION_GUIDE.md) - Room-by-room
examples
- [ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md](ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md) -
Complete system design
**Files**:
- `packages/adaptive_lighting_global.yaml` - Required for all rooms
- `packages/adaptive_lighting_bedroom_template.yaml` - Template for bedrooms
- `packages/adaptive_lighting_living_room_template.yaml` - Template for common
areas
- `packages/adaptive_lighting_simple_template.yaml` - Template for simple rooms
- `blueprints/automation/inovelli_mode_cycling.yaml` - Config button mode
cycling
- `blueprints/automation/inovelli_button_actions.yaml` - Multi-tap actions
- `blueprints/automation/presence_mode_reset.yaml` - Auto-reset on room exit
### Import URLs
**Blueprints**:
```
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/blueprints/automation/inovelli_mode_cycling.yaml
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/blueprints/automation/inovelli_button_actions.yaml
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/blueprints/automation/presence_mode_reset.yaml
```
---
## Occupancy Controlled Lights Blueprint
Automatically control lights based on occupancy sensors with adaptive lighting support. Perfect for any room where you want lights to turn on when someone enters and turn off when they leave.
### Import URL
```
https://git.johnogle.info/johno/home-assistant-blueprints/raw/branch/main/occupancy_controlled_lights.yaml
```
### Installation
**Method 1: Import via UI**
1. Go to Settings → Automations & Scenes → Blueprints
2. Click "Import Blueprint" (blue button, bottom right)
3. Paste the import URL above
4. Click "Preview" then "Import"
**Method 2: Manual Installation**
1. Download the blueprint file
2. Place it in `/config/blueprints/automation/occupancy_controlled_lights.yaml`
3. Restart Home Assistant or reload automations
### Features
- **Occupancy-based control**: Automatically turns lights on/off based on presence
- **Adaptive lighting support**: Optional integration with Adaptive Lighting component
- **Configurable transitions**: Set different fade times for on/off
- **Fallback support**: Works with or without adaptive lighting
- **Multiple light support**: Control single lights or groups
### Configuration Options
| Input | Description | Default |
|-------|-------------|---------|
| **Occupancy Sensor** | Binary sensor that detects occupancy/presence | Required |
| **Lights** | Light entities to control | Required |
| **Adaptive Lighting Switch** | Adaptive lighting switch for this room. Leave empty to use simple on/off without adaptive lighting. | Optional |
| **Turn On Transition** | Transition time when turning lights on (seconds) | 5 |
| **Turn Off Transition** | Transition time when turning lights off (seconds) | 15 |
| **Adapt Brightness** | Whether to adapt brightness with adaptive lighting | Yes |
| **Adapt Color** | Whether to adapt color with adaptive lighting | Yes |
### Usage Examples
#### Example 1: Basic Room with Adaptive Lighting
**Configuration**:
- **Occupancy Sensor**: `binary_sensor.living_room_occupancy`
- **Lights**: `light.living_room_lights`
- **Adaptive Lighting Switch**: `switch.adaptive_lighting_living_room`
- **Turn On Transition**: 3 seconds
- **Turn Off Transition**: 10 seconds
#### Example 2: Simple On/Off Mode (without Adaptive Lighting)
**Use Case**: Control lights with simple on/off without adaptive lighting adjustments.
**Configuration**:
- **Occupancy Sensor**: `binary_sensor.kitchen_motion`
- **Lights**: `light.kitchen_ceiling`, `light.kitchen_under_cabinet`
- **Adaptive Lighting Switch**: Leave empty (default)
- **Turn On Transition**: 1 second
- **Turn Off Transition**: 5 seconds
- **Adapt Brightness**: Not applicable (no adaptive lighting switch)
- **Adapt Color**: Not applicable (no adaptive lighting switch)
#### Example 3: Bedroom with Gentle Transitions
**Configuration**:
- **Occupancy Sensor**: `binary_sensor.bedroom_presence`
- **Lights**: `light.bedroom_lights`
- **Adaptive Lighting Switch**: `switch.adaptive_lighting_bedroom`
- **Turn On Transition**: 10 seconds (gentle wake-up)
- **Turn Off Transition**: 30 seconds (gradual fade)
### How It Works
1. **Occupancy Detected**: When the sensor state changes to "on" (occupied):
- If an Adaptive Lighting switch is configured AND enabled, applies adaptive lighting settings
- If the Adaptive Lighting switch is left empty OR is disabled, turns lights on with simple on/off using the specified transition time
2. **No Occupancy**: When the sensor state changes to "off" (not occupied):
- Turns off all specified lights with configured transition time
### Tips
- **Sensor Selection**: Works best with presence sensors (mmWave) for continuous detection
- **Transition Times**: Longer transitions feel more natural but may delay response
- **Adaptive Lighting**: Requires the Adaptive Lighting integration to be installed
- **Light Groups**: You can target light groups for easier management
### Troubleshooting
**Lights not turning on:**
- Verify occupancy sensor is working and changing state
- Check that light entities are correct and responsive
- Ensure adaptive lighting switch exists if specified
**Lights turning off too quickly:**
- Check occupancy sensor timeout settings
- Some PIR sensors have short detection windows
**Adaptive lighting not working:**
- Verify Adaptive Lighting integration is installed
- Check that the switch entity exists and is enabled
- Make sure the switch covers the target lights
## Multi-Press Action Blueprint ## Multi-Press Action Blueprint
Trigger different actions based on how many times an entity changes state rapidly. Perfect for light switches, buttons, or any entity where you want single, double, triple, or quad-press actions. Trigger different actions based on how many times an entity changes state rapidly. Perfect for light switches, buttons, or any entity where you want single, double, triple, or quad-press actions.

200
ROOM_CONFIGURATION_GUIDE.md Normal file
View File

@@ -0,0 +1,200 @@
# Room Configuration Guide
Complete examples of configuring different room types with the Adaptive
Lighting Mode System.
## Example 1: Master Bedroom
**Goal**: Full control with optional AL, reading/sleep modes, weekend mode
**Hardware**:
- Inovelli Blue Dimmer: `bedroom_switch` (Zigbee2MQTT name)
- Lights: `light.bedroom_ceiling`, `light.bedroom_lamp_1`,
`light.bedroom_lamp_2`
- No presence sensor (privacy)
**Adaptive Lighting Configuration** (in `configuration.yaml`):
```yaml
adaptive_lighting:
- name: bedroom
lights:
- light.bedroom_ceiling
- light.bedroom_lamp_1
- light.bedroom_lamp_2
interval: 90
transition: 45
take_over_control: true
autoreset_control_seconds: 3600 # 1 hour gentle reset
```
**Package File** (`packages/adaptive_lighting_master_bedroom.yaml`):
Copy from `adaptive_lighting_bedroom_template.yaml`, customize:
- Modes: Adaptive, Reading, Relaxing, Sleep, Manual Override
- Weekend mode enabled
- Default mode: Adaptive
**Blueprint Automations** (create via UI):
1. **Config Button Mode Cycling**:
- Blueprint: Inovelli Mode Cycling
- Switch Action Event: `event.bedroom_switch_action`
- Mode Input Select: `input_select.bedroom_lighting_mode`
- LED Color Entity: `number.bedroom_switch_led_color_when_on`
- Zigbee2MQTT Device Name: `bedroom_switch`
2. **Button Actions**:
- Blueprint: Inovelli Button Actions
- Switch Action Event: `event.bedroom_switch_action`
- AL Switch: `switch.adaptive_lighting_bedroom`
- Target Lights: `light.bedroom_ceiling`, `light.bedroom_lamp_1`,
`light.bedroom_lamp_2`
- Auto-Reset: 30 minutes
**Testing**:
- [ ] Press config button → mode cycles through all 5 modes
- [ ] LED changes color for each mode
- [ ] Double-tap up → brightness boosts
- [ ] Weekend mode enables Friday 10pm
- [ ] Sunrise shifts to 10am on weekend
## Example 2: Living Room (Common Area)
**Goal**: Entertainment modes (Theater, Party), presence control
**Hardware**:
- Inovelli Blue Dimmer: `living_room_switch`
- Lights: `light.living_room_ceiling`, `light.living_room_lamp_1`
- Presence: `binary_sensor.living_room_occupancy`
**Package File** (`packages/adaptive_lighting_living_room.yaml`):
Copy from `adaptive_lighting_living_room_template.yaml`
- Modes: Adaptive, Theater, Party, Reading
- Auto-reset mode to Adaptive when lights turn off
**Blueprint Automations**:
1. **Config Button Mode Cycling** (same as bedroom)
2. **Button Actions** (same as bedroom, adjust auto-reset to 15 min)
3. **Presence Mode Reset**:
- Occupancy Sensors: `binary_sensor.living_room_occupancy`
- Empty Delay: 5 minutes
- AL Switch: `switch.adaptive_lighting_living_room`
- Mode Input Select: `input_select.living_room_lighting_mode`
- Default Mode: `Adaptive`
**Testing**:
- [ ] Enter room → lights turn on (via separate occupancy automation)
- [ ] Press config button → cycles through 4 modes
- [ ] Set to Theater mode, leave room → after 5 min, resets to Adaptive
- [ ] Manual boost → leave room → manual control clears
## Example 3: Bathroom (Simple)
**Goal**: Always Adaptive, brightness boost only
**Hardware**:
- Inovelli Blue Dimmer: `bathroom_switch`
- Lights: `light.bathroom_ceiling`, `light.bathroom_vanity`
- Presence: `binary_sensor.bathroom_occupancy`
**Package File** (`packages/adaptive_lighting_bathroom.yaml`):
Copy from `adaptive_lighting_simple_template.yaml`
- No modes (Adaptive only)
- No weekend mode
- Simple reset on presence end
**Blueprint Automations**:
1. **Button Actions ONLY**:
- Double-tap up: Boost brightness
- Triple-tap down: Night light
- Auto-reset: 10 minutes
2. **Presence Mode Reset**:
- Reset manual control when empty 5 minutes
- No mode reset (no input_select)
**Testing**:
- [ ] Double-tap up → brightness boosts
- [ ] Leave bathroom 5 min → manual control clears
- [ ] Triple-tap down → night light mode
- [ ] No config button action (not configured)
## Entity ID Quick Reference
### Finding Your Entities
**Inovelli Switch Entities** (via Zigbee2MQTT):
```
event.{device_name}_action # Button presses (event entity)
number.{device_name}_led_color_when_on
number.{device_name}_led_color_when_off
number.{device_name}_led_intensity_when_on
select.{device_name}_smart_bulb_mode
select.{device_name}_button_delay
```
**Adaptive Lighting Entities**:
```
switch.adaptive_lighting_{name}
switch.adaptive_lighting_sleep_mode_{name}
switch.adaptive_lighting_adapt_brightness_{name}
switch.adaptive_lighting_adapt_color_{name}
```
**Your Input Helpers**:
```
input_select.{room}_lighting_mode
input_boolean.{room}_weekend_mode
```
## Common Customizations
### Add a New Mode
1. Edit package file, add mode to `input_select`:
```yaml
input_select:
bedroom_lighting_mode:
options:
- "Adaptive"
- "Reading"
- "NEW MODE HERE" # Add this
```
2. Add color mapping to global package (or use existing color)
3. Add mode application to automation:
```yaml
- conditions: "{{ mode == 'NEW MODE HERE' }}"
sequence:
- service: adaptive_lighting.change_switch_settings
data:
min_brightness: 50
max_brightness: 80
# ... settings
```
4. Reload YAML configuration
### Change Auto-Reset Timeout
Edit blueprint automation via UI:
- Settings → Automations → [Your button action automation]
- Click Edit
- Adjust "Auto-Reset Timeout" slider
- Save
### Disable Weekend Mode
Comment out weekend mode automations in package file:
```yaml
# - id: bedroom_weekend_mode_auto_enable
# alias: "Bedroom: Enable Weekend Mode Friday/Saturday"
# # ... entire automation
```
Reload YAML configuration.

View File

@@ -0,0 +1,163 @@
---
# blueprints/automation/inovelli_button_actions.yaml
#
# Inovelli Button Actions for Adaptive Lighting
#
# Implements multi-tap actions:
# - Double tap up: Brightness boost (+50% from current AL setting)
# - Double tap down: Return to Adaptive Lighting control
# - Triple tap up: Maximum brightness (100%, neutral white)
# - Triple tap down: Night light mode (5%, warm red)
#
# Features:
# - Auto-reset after configurable timeout
# - Reads current AL settings for relative boost
# - Works with any Inovelli Blue Dimmer via Zigbee2MQTT
#
# Requirements:
# - Inovelli Blue Dimmer (VZM31-SN) with buttonDelay >= 500ms
# - Adaptive Lighting switch for the room
# - Light entities to control
#
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 308-421
blueprint:
name: Inovelli Button Actions for Adaptive Lighting
description: Multi-tap brightness controls with adaptive lighting integration
domain: automation
input:
switch_action_event:
name: Switch Action Event
description: Event entity that reports button presses (event.xxx_action)
selector:
entity:
domain: event
adaptive_lighting_switch:
name: Adaptive Lighting Switch
description: The AL switch entity for this room
selector:
entity:
domain: switch
integration: adaptive_lighting
target_lights:
name: Target Lights
description: Light entities to control
selector:
target:
entity:
domain: light
auto_reset_minutes:
name: Auto-Reset Timeout (minutes)
description: Minutes before returning to AL after manual boost
default: 10
selector:
number:
min: 0
max: 120
step: 5
unit_of_measurement: minutes
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: !input switch_action_event
condition:
- condition: template
value_template: >-
{{
state_attr(trigger.entity_id, 'event_type') in
['up_double', 'down_double', 'up_triple', 'down_triple']
}}
action:
- variables:
action: "{{ state_attr(trigger.entity_id, 'event_type') }}"
al_switch: !input adaptive_lighting_switch
lights: !input target_lights
reset_minutes: !input auto_reset_minutes
- choose:
# ========================================================================
# DOUBLE TAP UP - Brightness Boost
# ========================================================================
- conditions: "{{ action == 'up_double' }}"
sequence:
- variables:
current_brightness: >-
{{ state_attr(al_switch, 'brightness_pct') | float(50) }}
boosted_brightness: "{{ [current_brightness + 50, 100] | min }}"
current_color_temp: >-
{{ state_attr(al_switch, 'color_temp_kelvin') | int(4000) }}
boosted_color_temp: >-
{{ [current_color_temp + 1000, 5500] | min }}
- service: light.turn_on
target: "{{ lights }}"
data:
brightness_pct: "{{ boosted_brightness }}"
color_temp_kelvin: "{{ boosted_color_temp }}"
transition: 1
# Auto-reset after timeout
- delay:
minutes: "{{ reset_minutes }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ al_switch }}"
manual_control: false
# ========================================================================
# DOUBLE TAP DOWN - Return to AL
# ========================================================================
- conditions: "{{ action == 'down_double' }}"
sequence:
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ al_switch }}"
manual_control: false
# ========================================================================
# TRIPLE TAP UP - Max Brightness (Neutral White)
# ========================================================================
- conditions: "{{ action == 'up_triple' }}"
sequence:
- service: light.turn_on
target: "{{ lights }}"
data:
brightness_pct: 100
color_temp_kelvin: 4000
transition: 0.5
# Auto-reset after timeout
- delay:
minutes: "{{ reset_minutes }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ al_switch }}"
manual_control: false
# ========================================================================
# TRIPLE TAP DOWN - Night Light
# ========================================================================
- conditions: "{{ action == 'down_triple' }}"
sequence:
- service: light.turn_on
target: "{{ lights }}"
data:
brightness_pct: 5
rgb_color: [255, 50, 0]
transition: 1
# Auto-reset after timeout
- delay:
minutes: "{{ reset_minutes }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ al_switch }}"
manual_control: false

View File

@@ -0,0 +1,96 @@
# blueprints/automation/inovelli_mode_cycling.yaml
#
# Inovelli Config Button Mode Cycling
#
# Cycles through lighting modes when the config button is pressed on an
# Inovelli Blue Dimmer Switch (VZM31-SN) via Zigbee2MQTT.
#
# Features:
# - Cycles through available modes in input_select
# - Updates LED color to match new mode (ROYGBIV scheme)
# - Flashes LED to confirm mode change (0.5-second pulse)
#
# Requirements:
# - Inovelli Blue Dimmer (VZM31-SN) paired with Zigbee2MQTT
# - input_select helper with available modes
# - packages/adaptive_lighting_global.yaml for mode colors
#
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 144-182
blueprint:
name: Inovelli Config Button Mode Cycling
description: Press config button to cycle through lighting modes with LED feedback
domain: automation
input:
switch_action_event:
name: Switch Action Event
description: The event entity that reports button presses (event.xxx_action)
selector:
entity:
domain: event
mode_input_select:
name: Mode Input Select
description: The input_select helper that tracks current lighting mode
selector:
entity:
domain: input_select
led_color_entity:
name: LED Color Entity
description: The number entity for LED color when on (number.xxx_led_color_when_on)
selector:
entity:
domain: number
zigbee2mqtt_device_name:
name: Zigbee2MQTT Device Name
description: The device name in Zigbee2MQTT (for LED flash effect via MQTT). Example "bedroom_switch"
selector:
text:
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: !input switch_action_event
condition:
- condition: state
entity_id: !input switch_action_event
attribute: event_type
state: "config_single"
action:
- variables:
mode_select: !input mode_input_select
zigbee2mqtt_device_name: !input zigbee2mqtt_device_name
current_mode: "{{ states(mode_select) }}"
available_modes: "{{ state_attr(mode_select, 'options') }}"
current_index: "{{ available_modes.index(current_mode) }}"
next_index: "{{ (current_index + 1) % (available_modes | length) }}"
next_mode: "{{ available_modes[next_index] }}"
mode_colors: "{{ states('input_text.adaptive_lighting_mode_colors') | from_json }}"
next_color: "{{ mode_colors.get(next_mode, 170) }}"
# Change to next mode
- service: input_select.select_option
target:
entity_id: !input mode_input_select
data:
option: "{{ next_mode }}"
# Update LED color
- service: number.set_value
target:
entity_id: !input led_color_entity
data:
value: "{{ next_color }}"
# Flash LED to confirm mode change (0.5-second pulse)
- service: mqtt.publish
data:
topic: "zigbee2mqtt/{{ zigbee2mqtt_device_name }}/set"
payload: >-
{"led_effect": {"effect": "pulse", "color": {{ next_color }}, "level": 100, "duration": 0.5}}

View File

@@ -0,0 +1,116 @@
---
# blueprints/automation/presence_mode_reset.yaml
#
# Presence-Based Mode and Manual Control Reset
#
# Automatically resets lighting mode and clears manual control when room
# becomes unoccupied for a configurable duration.
#
# Use Cases:
# - Reset Theater mode to Adaptive when leaving living room
# - Clear manual brightness boosts when bedroom becomes empty
# - Return bathroom to normal AL after presence ends
#
# Requirements:
# - Binary sensor(s) for occupancy/presence detection
# - Adaptive Lighting switch (optional - for manual control reset)
# - Mode input_select (optional - for mode reset)
#
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 437-451,
# 709-719
blueprint:
name: Presence-Based Mode and Manual Control Reset
description: >-
Reset lighting modes and AL manual control when room becomes empty
domain: automation
input:
occupancy_sensors:
name: Occupancy Sensors
description: Binary sensor(s) that detect room occupancy
selector:
entity:
domain: binary_sensor
device_class: occupancy
multiple: true
empty_delay:
name: Empty Delay
description: How long room must be empty before reset
default: 5
selector:
number:
min: 0
max: 60
step: 1
unit_of_measurement: minutes
adaptive_lighting_switch:
name: Adaptive Lighting Switch (Optional)
description: AL switch to reset manual control. Leave empty to skip.
default: {}
selector:
entity:
domain: switch
integration: adaptive_lighting
mode_input_select:
name: Mode Input Select (Optional)
description: Mode selector to reset to Adaptive. Leave empty to skip.
default: {}
selector:
entity:
domain: input_select
default_mode:
name: Default Mode
description: Mode to reset to when room becomes empty
default: "Adaptive"
selector:
text:
mode: restart
trigger:
- platform: state
entity_id: !input occupancy_sensors
to: 'off'
for:
minutes: !input empty_delay
action:
- variables:
occupancy_sensors: !input occupancy_sensors
al_switch: !input adaptive_lighting_switch
mode_select: !input mode_input_select
default_mode: !input default_mode
# Ensure ALL sensors are off (room is truly empty)
- condition: template
value_template: >-
{{
expand(occupancy_sensors) |
selectattr('state', 'eq', 'on') |
list | count == 0
}}
# Reset manual control if AL switch provided
- if:
- condition: template
value_template: "{{ al_switch not in [none, {}, ''] }}"
then:
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ al_switch }}"
manual_control: false
# Reset mode if input_select provided
- if:
- condition: template
value_template: "{{ mode_select not in [none, {}, ''] }}"
then:
- service: input_select.select_option
target:
entity_id: "{{ mode_select }}"
data:
option: "{{ default_mode }}"

View File

@@ -0,0 +1,66 @@
---
# examples/test_room_config.yaml
#
# Test configuration for validating the Adaptive Lighting Mode System
# without real Inovelli hardware or Adaptive Lighting integration.
#
# This uses template sensors and manual input helpers to simulate the system.
input_select:
test_room_lighting_mode:
name: "Test Room Lighting Mode"
options:
- "Adaptive"
- "Reading"
- "Sleep"
initial: "Adaptive"
sensor:
- platform: template
sensors:
test_switch_action:
friendly_name: "Test Switch Action"
value_template: "{{ states('input_text.test_switch_action_sim') }}"
input_text:
test_switch_action_sim:
name: "Simulate Switch Action"
initial: "none"
input_number:
test_led_color:
name: "Test LED Color"
min: 0
max: 255
step: 1
initial: 170
# Automation to test mode cycling logic
automation:
- id: test_mode_cycling
alias: "Test: Mode Cycling"
trigger:
- platform: state
entity_id: input_text.test_switch_action_sim
to: "config_single"
variables:
mode_select: input_select.test_room_lighting_mode
current_mode: "{{ states(mode_select) }}"
available_modes: "{{ state_attr(mode_select, 'options') }}"
current_index: "{{ available_modes.index(current_mode) }}"
next_index: "{{ (current_index + 1) % (available_modes | length) }}"
next_mode: "{{ available_modes[next_index] }}"
mode_colors: >-
{{ states('input_text.adaptive_lighting_mode_colors') | from_json }}
next_color: "{{ mode_colors.get(next_mode, 170) }}"
action:
- service: input_select.select_option
target:
entity_id: input_select.test_room_lighting_mode
data:
option: "{{ next_mode }}"
- service: input_number.set_value
target:
entity_id: input_number.test_led_color
data:
value: "{{ next_color }}"

View File

@@ -9,6 +9,14 @@ blueprint:
selector: selector:
entity: {} entity: {}
press_counter:
name: Multi-Press Counter
description: House-wide counter helper for tracking presses (create counter.multi_press_counter)
default: counter.multi_press_counter
selector:
entity:
domain: counter
time_window: time_window:
name: Time Window name: Time Window
description: Maximum time between presses (in seconds) description: Maximum time between presses (in seconds)
@@ -64,58 +72,56 @@ trigger:
action: action:
- variables: - variables:
press_count: 1
time_window: !input time_window time_window: !input time_window
immediate: !input immediate_single_press immediate: !input immediate_single_press
counter_entity: !input press_counter
# Increment the counter (each restart = new press)
- action: counter.increment
target:
entity_id: !input press_counter
# Execute single press immediately if enabled # Execute single press immediately if enabled
- if: - if:
- condition: template - condition: template
value_template: "{{ immediate }}" value_template: "{{ immediate and states(counter_entity) | int == 1 }}"
then: then:
- choose: - choose:
- conditions: [] - conditions: []
sequence: !input single_press_action sequence: !input single_press_action
# Wait for additional presses # Wait for the time window to see if more presses come
- repeat: - delay:
while: seconds: "{{ time_window }}"
- condition: template
value_template: "{{ press_count < 4 }}"
sequence:
- wait_for_trigger:
- platform: state
entity_id: !input trigger_entity
timeout:
seconds: "{{ time_window }}"
continue_on_timeout: true
- if: # Get final press count and execute appropriate action
- condition: template - variables:
value_template: "{{ wait.trigger is not none }}" final_count: "{{ states(counter_entity) | int }}"
then:
- variables: # Reset counter before executing actions
press_count: "{{ press_count + 1 }}" - action: counter.reset
target:
entity_id: !input press_counter
# Execute action based on final press count # Execute action based on final press count
- choose: - choose:
# Only run single press if NOT immediate (delayed mode) # Only run single press if NOT immediate (delayed mode)
- conditions: - conditions:
- condition: template - condition: template
value_template: "{{ press_count == 1 and not immediate }}" value_template: "{{ final_count == 1 and not immediate }}"
sequence: !input single_press_action sequence: !input single_press_action
- conditions: - conditions:
- condition: template - condition: template
value_template: "{{ press_count == 2 }}" value_template: "{{ final_count == 2 }}"
sequence: !input double_press_action sequence: !input double_press_action
- conditions: - conditions:
- condition: template - condition: template
value_template: "{{ press_count == 3 }}" value_template: "{{ final_count == 3 }}"
sequence: !input triple_press_action sequence: !input triple_press_action
- conditions: - conditions:
- condition: template - condition: template
value_template: "{{ press_count == 4 }}" value_template: "{{ final_count >= 4 }}"
sequence: !input quad_press_action sequence: !input quad_press_action

View File

@@ -0,0 +1,116 @@
blueprint:
name: Occupancy Controlled Lights with Adaptive Lighting
description: Automatically turn lights on/off based on multiple occupancy sensors with adaptive lighting support. Lights turn on when any sensor detects motion and turn off only when all sensors are clear for the configured delay.
domain: automation
input:
occupancy_sensors:
name: Occupancy Sensors
description: Binary sensors that detect occupancy/presence in the area
selector:
entity:
domain: binary_sensor
device_class: occupancy
multiple: true
lights:
name: Lights
description: Light entities to control
selector:
target:
entity:
domain: light
adaptive_lighting_switch:
name: Adaptive Lighting Switch
description: (Optional) Adaptive lighting switch entity for this room. If left empty, lights will turn on/off directly without adaptive lighting adjustments.
default: {}
selector:
entity:
domain: switch
integration: adaptive_lighting
turn_on_transition:
name: Turn On Transition
description: Transition time in seconds when turning lights on
default: 5
selector:
number:
min: 0
max: 300
step: 1
unit_of_measurement: seconds
turn_off_transition:
name: Turn Off Transition
description: Transition time in seconds when turning lights off
default: 15
selector:
number:
min: 0
max: 300
step: 1
unit_of_measurement: seconds
adapt_brightness:
name: Adapt Brightness
description: Whether to adapt brightness when turning on lights (only applies when an Adaptive Lighting switch is configured)
default: true
selector:
boolean:
adapt_color:
name: Adapt Color
description: Whether to adapt color when turning on lights (only applies when an Adaptive Lighting switch is configured)
default: true
selector:
boolean:
off_delay:
name: Off Delay
description: Time to wait after no motion before turning lights off
default: 0
selector:
number:
min: 0
max: 3600
step: 1
unit_of_measurement: seconds
trigger:
- platform: state
entity_id: !input occupancy_sensors
condition: []
action:
- variables:
occupancy_sensors: !input occupancy_sensors
adaptive_lighting_switch: !input adaptive_lighting_switch
- choose:
- conditions:
- condition: template
value_template: "{{ expand(occupancy_sensors) | selectattr('state', 'eq', 'on') | list | count > 0 }}"
sequence:
- if:
- condition: template
value_template: "{{ adaptive_lighting_switch != none and adaptive_lighting_switch != {} and states(adaptive_lighting_switch) == 'on' }}"
then:
- action: adaptive_lighting.apply
data:
entity_id: !input adaptive_lighting_switch
turn_on_lights: true
transition: !input turn_on_transition
adapt_brightness: !input adapt_brightness
adapt_color: !input adapt_color
else:
- action: light.turn_on
target: !input lights
data:
transition: !input turn_on_transition
- conditions:
- condition: template
value_template: "{{ expand(occupancy_sensors) | selectattr('state', 'eq', 'on') | list | count == 0 }}"
sequence:
- delay:
seconds: !input off_delay
- condition: template
value_template: "{{ expand(occupancy_sensors) | selectattr('state', 'eq', 'on') | list | count == 0 }}"
- action: light.turn_off
target: !input lights
data:
transition: !input turn_off_transition
mode: restart

View File

@@ -0,0 +1,235 @@
# packages/adaptive_lighting_bedroom_template.yaml
#
# Adaptive Lighting Mode System - Bedroom Template
#
# CUSTOMIZATION INSTRUCTIONS:
# 1. Copy this file to a new file named after your room (e.g., adaptive_lighting_master_bedroom.yaml)
# 2. Search and replace "bedroom" with your room name throughout
# 3. Update entity IDs to match your actual devices
# 4. Adjust available modes in input_select as desired
# 5. Customize mode settings in the automation
# 6. Place in config/packages/ directory
#
# Prerequisites:
# - packages/adaptive_lighting_global.yaml loaded
# - Adaptive Lighting integration installed
# - Adaptive Lighting switch created for this room
# - Inovelli Blue Dimmer paired with Zigbee2MQTT in Smart Bulb Mode
#
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 1589-1672
# =============================================================================
# INPUT HELPERS
# =============================================================================
input_select:
bedroom_lighting_mode:
name: "Bedroom Lighting Mode"
options:
- "Adaptive" # Standard AL following sun
- "Reading" # Bright, cool white
- "Relaxing" # Dim, warm white
- "Sleep" # Very dim, red/amber
- "Manual Override" # Full user control, AL paused
initial: "Adaptive"
icon: mdi:lightbulb-multiple
input_boolean:
bedroom_weekend_mode:
name: "Bedroom Weekend Mode"
icon: mdi:sleep
initial: off
# =============================================================================
# AUTOMATIONS
# =============================================================================
automation:
# ---------------------------------------------------------------------------
# Mode Application
# ---------------------------------------------------------------------------
# When mode changes, apply appropriate Adaptive Lighting settings
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 192-306
# ---------------------------------------------------------------------------
- id: bedroom_apply_lighting_mode
alias: "Bedroom: Apply Lighting Mode Settings"
description: "Apply AL settings based on selected lighting mode"
mode: restart
trigger:
- platform: state
entity_id: input_select.bedroom_lighting_mode
- platform: homeassistant
event: start
variables:
mode: "{{ states('input_select.bedroom_lighting_mode') }}"
switch_entity: "switch.adaptive_lighting_bedroom" # UPDATE THIS
mode_colors: "{{ states('input_text.adaptive_lighting_mode_colors') | from_json }}"
action:
- choose:
# Adaptive Mode - Standard AL following sun
- conditions:
- condition: template
value_template: "{{ mode == 'Adaptive' }}"
sequence:
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data:
use_defaults: configuration
# Reading Mode - Bright cool white
# Option 1: Read from centralized settings (recommended for maintainability)
- conditions:
- condition: template
value_template: "{{ mode == 'Reading' }}"
sequence:
- variables:
settings: "{{ states('input_text.adaptive_lighting_settings_reading') | from_json }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data: "{{ settings | combine({'use_defaults': 'current'}) }}"
# Alternative: Hardcode values directly (simpler but less maintainable)
# - conditions:
# - condition: template
# value_template: "{{ mode == 'Reading' }}"
# sequence:
# - service: adaptive_lighting.change_switch_settings
# data:
# min_brightness: 80
# max_brightness: 100
# min_color_temp: 4500
# max_color_temp: 5500
# transition: 2
# use_defaults: current
# Relaxing Mode - Dim warm white
- conditions:
- condition: template
value_template: "{{ mode == 'Relaxing' }}"
sequence:
- variables:
settings: "{{ states('input_text.adaptive_lighting_settings_relaxing') | from_json }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data: "{{ settings | combine({'use_defaults': 'current'}) }}"
# Sleep Mode - Very dim red/amber
- conditions:
- condition: template
value_template: "{{ mode == 'Sleep' }}"
sequence:
- variables:
settings: "{{ states('input_text.adaptive_lighting_settings_sleep') | from_json }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data: "{{ settings | combine({'use_defaults': 'current'}) }}"
# Manual Override - Pause AL completely
- conditions:
- condition: template
value_template: "{{ mode == 'Manual Override' }}"
sequence:
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: true
# Update LED color on Inovelli switch to match mode
# NOTE: Update entity_id to match your switch
- service: number.set_value
target:
entity_id: number.bedroom_switch_led_color_when_on # UPDATE THIS
data:
value: "{{ mode_colors.get(mode, 170) }}"
# ---------------------------------------------------------------------------
# Weekend Mode - Auto Enable/Disable
# ---------------------------------------------------------------------------
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 894-926
# ---------------------------------------------------------------------------
- id: bedroom_weekend_mode_auto_enable
alias: "Bedroom: Enable Weekend Mode Friday/Saturday"
trigger:
- platform: time
at: "22:00:00"
condition:
- condition: time
weekday: ["fri", "sat"]
action:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.bedroom_weekend_mode
- id: bedroom_weekend_mode_auto_disable
alias: "Bedroom: Disable Weekend Mode Sunday-Thursday"
trigger:
- platform: time
at: "22:00:00"
condition:
- condition: time
weekday: ["sun", "mon", "tue", "wed", "thu"]
action:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.bedroom_weekend_mode
# ---------------------------------------------------------------------------
# Weekend Mode - Apply AL Adjustments
# ---------------------------------------------------------------------------
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 928-961
# ---------------------------------------------------------------------------
- id: bedroom_weekend_mode_apply
alias: "Bedroom: Apply Weekend Mode AL Adjustments"
trigger:
- platform: state
entity_id: input_boolean.bedroom_weekend_mode
- platform: homeassistant
event: start
variables:
weekend_mode: "{{ is_state('input_boolean.bedroom_weekend_mode', 'on') }}"
switch_entity: "switch.adaptive_lighting_bedroom" # UPDATE THIS
action:
- choose:
- conditions:
- condition: template
value_template: "{{ weekend_mode }}"
sequence:
# Weekend settings: Later sunrise, lower max brightness
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data:
sunrise_time: "10:00:00"
sunset_time: "01:00:00"
max_brightness: 60
use_defaults: current
- conditions:
- condition: template
value_template: "{{ not weekend_mode }}"
sequence:
# Weekday settings: Reset to defaults
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data:
use_defaults: configuration

View File

@@ -0,0 +1,114 @@
# packages/adaptive_lighting_global.yaml
#
# Global constants for Adaptive Lighting Mode System
# This file is shared across all rooms and should be version controlled.
#
# To use: Place in config/packages/ directory
# Enable packages in configuration.yaml:
# homeassistant:
# packages: !include_dir_named packages/
# =============================================================================
# MODE COLOR MAPPINGS (ROYGBIV Scheme)
# =============================================================================
# These colors are used for LED feedback on Inovelli switches
# Values are hue (0-255) for Zigbee2MQTT ledColorWhenOn/Off parameter
#
# Reference ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 112-131
# =============================================================================
input_text:
adaptive_lighting_mode_colors:
name: "AL Mode Color Mappings (JSON)"
max: 255
# JSON minified to fit in 255 char limit
initial: >-
{"Adaptive":170,"Reading":42,"Relaxing":21,"Sleep":0,
"Manual Override":212,"Theater":127,"Party":234,"Homework":85,
"Play":148,"Cooking":42,"Dining":21,"Cleanup":170}
# =============================================================================
# MODE SETTINGS DEFINITIONS
# =============================================================================
# Each mode has its own input_text helper to stay within 255 char limit
# Room automations read these to apply appropriate AL settings
# =============================================================================
# Adaptive mode - uses default AL configuration
adaptive_lighting_settings_adaptive:
name: "AL Settings: Adaptive"
max: 255
initial: '{"use_defaults":"configuration"}'
# Reading mode - bright, cool white
adaptive_lighting_settings_reading:
name: "AL Settings: Reading"
max: 255
initial: '{"min_brightness":80,"max_brightness":100,"min_color_temp":4500,"max_color_temp":5500,"transition":2}'
# Relaxing mode - dim, warm white
adaptive_lighting_settings_relaxing:
name: "AL Settings: Relaxing"
max: 255
initial: '{"min_brightness":20,"max_brightness":40,"min_color_temp":2000,"max_color_temp":2500,"transition":5}'
# Sleep mode - very dim red/amber
adaptive_lighting_settings_sleep:
name: "AL Settings: Sleep"
max: 255
initial: '{"min_brightness":1,"max_brightness":5,"min_color_temp":2000,"sleep_rgb_color":[255,50,0],"transition":2}'
# Theater mode - dim, cool for movies
adaptive_lighting_settings_theater:
name: "AL Settings: Theater"
max: 255
initial: '{"min_brightness":5,"max_brightness":20,"min_color_temp":3000,"max_color_temp":4000,"transition":3}'
# Party mode - bright, dynamic for socializing
adaptive_lighting_settings_party:
name: "AL Settings: Party"
max: 255
initial: '{"min_brightness":60,"max_brightness":90,"min_color_temp":3500,"max_color_temp":4500,"transition":1}'
# Homework mode - bright, neutral for focus
adaptive_lighting_settings_homework:
name: "AL Settings: Homework"
max: 255
initial: '{"min_brightness":85,"max_brightness":100,"min_color_temp":4000,"max_color_temp":5000,"transition":2}'
# Play mode - medium bright, energizing
adaptive_lighting_settings_play:
name: "AL Settings: Play"
max: 255
initial: '{"min_brightness":60,"max_brightness":85,"min_color_temp":4000,"max_color_temp":5000,"transition":2}'
# Cooking mode - bright, cool task lighting
adaptive_lighting_settings_cooking:
name: "AL Settings: Cooking"
max: 255
initial: '{"min_brightness":90,"max_brightness":100,"min_color_temp":4500,"max_color_temp":5500,"transition":1}'
# Dining mode - medium, warm for meals
adaptive_lighting_settings_dining:
name: "AL Settings: Dining"
max: 255
initial: '{"min_brightness":40,"max_brightness":70,"min_color_temp":2500,"max_color_temp":3500,"transition":3}'
# Cleanup mode - bright, standard for cleaning
adaptive_lighting_settings_cleanup:
name: "AL Settings: Cleanup"
max: 255
initial: '{"min_brightness":80,"max_brightness":100,"min_color_temp":4000,"max_color_temp":5000,"transition":1}'
# Manual Override mode - pauses AL completely (no settings needed)
# =============================================================================
# USAGE NOTES
# =============================================================================
# To access mode colors in templates:
# {% set colors = states('input_text.adaptive_lighting_mode_colors') | from_json %}
# {{ colors.get('Reading', 170) }}
#
# To access mode settings in templates:
# {% set settings = states('input_text.adaptive_lighting_settings_reading') | from_json %}
# {{ settings.min_brightness }}

View File

@@ -0,0 +1,122 @@
# packages/adaptive_lighting_living_room_template.yaml
#
# Adaptive Lighting Mode System - Living Room Template
#
# CUSTOMIZATION INSTRUCTIONS:
# 1. Copy this file and rename for your room
# 2. Search and replace "living_room" with your room name
# 3. Update entity IDs to match your devices
# 4. Adjust modes as desired
# 5. Place in config/packages/ directory
#
# Reference: ADAPTIVE_LIGHTING_CONTROL_SYSTEM_DESIGN.md lines 1512-1587
# =============================================================================
# INPUT HELPERS
# =============================================================================
input_select:
living_room_lighting_mode:
name: "Living Room Lighting Mode"
options:
- "Adaptive"
- "Theater"
- "Party"
- "Reading"
initial: "Adaptive"
icon: mdi:lightbulb-multiple
# =============================================================================
# AUTOMATIONS
# =============================================================================
automation:
# ---------------------------------------------------------------------------
# Mode Application
# ---------------------------------------------------------------------------
- id: living_room_apply_lighting_mode
alias: "Living Room: Apply Lighting Mode Settings"
mode: restart
trigger:
- platform: state
entity_id: input_select.living_room_lighting_mode
- platform: homeassistant
event: start
variables:
mode: "{{ states('input_select.living_room_lighting_mode') }}"
switch_entity: "switch.adaptive_lighting_living_room" # UPDATE THIS
mode_colors: "{{ states('input_text.adaptive_lighting_mode_colors') | from_json }}"
action:
- choose:
- conditions: "{{ mode == 'Adaptive' }}"
sequence:
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data:
use_defaults: configuration
- conditions: "{{ mode == 'Theater' }}"
sequence:
- variables:
settings: "{{ states('input_text.adaptive_lighting_settings_theater') | from_json }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data: "{{ settings | combine({'use_defaults': 'current'}) }}"
- conditions: "{{ mode == 'Party' }}"
sequence:
- variables:
settings: "{{ states('input_text.adaptive_lighting_settings_party') | from_json }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data: "{{ settings | combine({'use_defaults': 'current'}) }}"
- conditions: "{{ mode == 'Reading' }}"
sequence:
- variables:
settings: "{{ states('input_text.adaptive_lighting_settings_reading') | from_json }}"
- service: adaptive_lighting.set_manual_control
data:
entity_id: "{{ switch_entity }}"
manual_control: false
- service: adaptive_lighting.change_switch_settings
target:
entity_id: "{{ switch_entity }}"
data: "{{ settings | combine({'use_defaults': 'current'}) }}"
- service: number.set_value
target:
entity_id: number.living_room_switch_led_color_when_on # UPDATE THIS
data:
value: "{{ mode_colors.get(mode, 170) }}"
# ---------------------------------------------------------------------------
# Auto-Reset Mode to Adaptive When Lights Turn Off
# ---------------------------------------------------------------------------
- id: living_room_reset_mode_on_off
alias: "Living Room: Reset Mode to Adaptive When Off"
trigger:
- platform: state
entity_id: light.living_room_lights # UPDATE THIS
to: 'off'
action:
- service: input_select.select_option
target:
entity_id: input_select.living_room_lighting_mode
data:
option: "Adaptive"

View File

@@ -0,0 +1,38 @@
# packages/adaptive_lighting_simple_template.yaml
#
# Adaptive Lighting Mode System - Simple Template
#
# For rooms that only need basic Adaptive Lighting without mode switching.
# Example: Bathrooms, closets, hallways
#
# CUSTOMIZATION INSTRUCTIONS:
# 1. Copy and rename for your room
# 2. Replace "simple_room" with your room name
# 3. Update entity IDs
# 4. This template has NO mode cycling (Adaptive only)
#
# For button actions like brightness boost, use the inovelli_button_actions blueprint
# =============================================================================
# CONFIGURATION
# =============================================================================
# No input_select needed - always in Adaptive mode
# =============================================================================
# AUTOMATIONS
# =============================================================================
automation:
# ---------------------------------------------------------------------------
# Ensure AL is Always Active
# ---------------------------------------------------------------------------
- id: simple_room_ensure_adaptive_lighting
alias: "Simple Room: Ensure Adaptive Lighting Active"
trigger:
- platform: homeassistant
event: start
action:
- service: adaptive_lighting.set_manual_control
data:
entity_id: switch.adaptive_lighting_simple_room # UPDATE THIS
manual_control: false

36
scripts/validate_yaml.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# scripts/validate_yaml.sh
#
# Validates YAML syntax for all Adaptive Lighting system files
set -e
echo "Validating Adaptive Lighting Mode System YAML files..."
echo "========================================================"
# Check if yamllint is installed
if ! command -v yamllint &> /dev/null; then
echo "ERROR: yamllint not found."
echo "Install with: pip install yamllint"
echo "Or run with: nix run nixpkgs#yamllint -- <files>"
exit 1
fi
# Validate packages
echo ""
echo "Validating packages..."
for file in packages/*.yaml; do
echo " - $file"
yamllint -d '{extends: default, rules: {line-length: {max: 120}}}' "$file"
done
# Validate blueprints
echo ""
echo "Validating blueprints..."
for file in blueprints/automation/*.yaml; do
echo " - $file"
yamllint -d '{extends: default, rules: {line-length: {max: 120}}}' "$file"
done
echo ""
echo "✓ All YAML files are valid!"