Summary
Implement intelligent device routing for notifications so messages are sent to the device a person is most likely to have with them, based on time of day, location, and device availability.
Motivation
Currently, notifications are sent to all devices simultaneously. This causes:
- Information overload across multiple devices
- Missed critical alerts if person isn't looking at primary device
- Wasted battery on smartwatch notifications during work hours
- No intelligence about device context
A smarter routing system would:
- Reduce notification fatigue
- Ensure messages reach the right device at the right time
- Improve accessibility and response time
- Adapt to user patterns and schedules
Implementation Approaches
Approach A: Context-Based (Time + Location)
Route based on time of day and person's location
Pros:
- ✅ Simple, predictable logic
- ✅ No external dependencies
- ✅ Works with existing presence system
- ✅ Easy to configure and debug
- ✅ Good starting point
Cons:
- ❌ Requires manual tuning per person
- ❌ Doesn't adapt to irregular schedules
- ❌ Doesn't track actual device availability
- ❌ Can't handle exceptions (person working from home, sick day, etc.)
Example Logic:
120: - if:
121: - condition: time
122: after: "09:00:00"
123: before: "17:00:00"
124: - condition: state
125: entity_id: person.danny
126: state: "work"
127: then:
128: - set: v_target_device: "notify.danny_laptop"
129: elif:
130: - condition: time
131: after: "07:00:00"
132: before: "09:00:00"
133: then:
134: - set: v_target_device: "notify.mobile_app_top_dog"
135: elif:
136: - condition: time
137: after: "19:00:00"
138: before: "23:00:00"
139: then:
140: - set: v_target_device: "notify.mobile_app_top_dog"
141: else:
142: - set: v_target_device: "none" # Quiet hours
143:
144: # Send to determined device
145: - if:
146: - condition: template
147: value_template: "{{ v_target_device != 'none' }}"
148: then:
149: - action: "{{ v_target_device }}"
150: data:
151: message: "{{ message }}"
Behavior Examples:
| Time |
Danny's Location |
Target Device |
| 09:00-17:00 |
work |
laptop (notify.danny_laptop) |
| 07:00-09:00 |
home |
phone (notify.mobile_app_top_dog) |
| 19:00-23:00 |
home |
phone (notify.mobile_app_top_dog) |
| 23:00-07:00 |
home |
none (quiet) or smartwatch only |
| 14:00 |
away |
phone (not at work) |
Configuration Required:
- input_datetime for work start/end times per person
- input_select for device preferences per time slot
- Person's location tracking (already configured)
Approach B: Availability-Based (Device State)
Route based on actual device availability: online status, battery level, last seen
Pros:
- ✅ Works with actual device state
- ✅ Handles unexpected scenarios
- ✅ Battery-aware (don't send if low battery)
- ✅ More reliable in practice
- ✅ Adapts to real-world device usage
Cons:
- ❌ More complex logic (~40-50 lines)
- ❌ Requires robust device tracking
- ❌ Database lookups for each notification
- ❌ Fallback logic must be well-designed
- ❌ Depends on device_tracker accuracy
Example Logic:
120: - if:
121: - condition: state
122: entity_id: device_tracker.danny_laptop
123: state: "home" # or specific location
124: - condition: numeric_state
125: entity_id: sensor.danny_laptop_battery
126: above: 20
127: then:
128: - set: v_target_device: "notify.danny_laptop"
129: elif:
130: - condition: state
131: entity_id: device_tracker.danny_phone
132: state: "home"
133: - condition: numeric_state
134: entity_id: sensor.danny_phone_battery
135: above: 10
136: then:
137: - set: v_target_device: "notify.mobile_app_top_dog"
138: elif:
139: - condition: state
140: entity_id: device_tracker.danny_smartwatch
141: state: "home"
142: - condition: numeric_state
143: entity_id: sensor.danny_smartwatch_battery
144: above: 5
145: then:
146: - set: v_target_device: "notify.danny_smartwatch"
147: else:
148: - set: v_target_device: "all" # Fallback: send to all
149:
150: # Send to determined device
151: - if:
152: - condition: template
153: value_template: "{{ v_target_device != 'none' }}"
154: then:
155: - action: "{{ v_target_device }}"
156: data:
157: message: "{{ message }}"
158: - elif: "{{ v_target_device == 'all' }}"
159: then:
160: # Fallback: send to all available devices
161: - parallel:
162: - action: notify.danny_laptop
163: - action: notify.mobile_app_top_dog
164: - action: notify.danny_smartwatch
Behavior Examples:
| Laptop |
Phone |
Smartwatch |
Target Device |
| online, 75% battery |
online, 40% battery |
online, 12% battery |
laptop |
| offline |
online, 40% battery |
online, 12% battery |
phone |
| online, 5% battery |
offline |
online, 8% battery |
smartwatch |
| offline |
offline |
offline |
all (send to all available) |
Configuration Required:
- device_tracker entities for each device
- battery sensors for each device
- Battery threshold constants (laptop: 20%, phone: 10%, watch: 5%)
- Location/availability status mapping
Approach C: Hybrid (Context + Availability) ⭐ Recommended
Combine time-based context routing with availability fallback for best results
Pros:
- ✅ Smart primary routing based on context
- ✅ Fallback to available devices if primary unavailable
- ✅ Handles edge cases and exceptions
- ✅ Battery-aware with intelligent fallback
- ✅ Flexible and adaptable
- ✅ Best of both approaches
Cons:
- ❌ Most complex to implement (~60-80 lines)
- ❌ Requires both time + device tracking setup
- ❌ More maintenance and tuning needed
- ❌ More points of failure
Example Logic:
120: # Determine primary device based on time/context
121: - variables:
122: v_primary_device: null
123: v_fallback_devices: []
124:
125: - if:
126: - condition: time
127: after: "09:00:00"
128: before: "17:00:00"
129: then:
130: - set:
131: v_primary_device: "notify.danny_laptop"
132: v_fallback_devices: ["notify.mobile_app_top_dog", "notify.danny_smartwatch"]
133: elif:
134: - condition: time
135: after: "19:00:00"
136: before: "23:00:00"
137: then:
138: - set:
139: v_primary_device: "notify.mobile_app_top_dog"
140: v_fallback_devices: ["notify.danny_laptop", "notify.danny_smartwatch"]
141: else:
142: - set:
143: v_primary_device: "notify.danny_smartwatch"
144: v_fallback_devices: ["notify.mobile_app_top_dog"]
145:
146: # Try primary device with availability checks
147: - if:
148: - condition: state
149: entity_id: device_tracker.danny_laptop
150: state: "home"
151: - condition: numeric_state
152: entity_id: sensor.danny_laptop_battery
153: above: 20
154: then:
155: - action: notify.danny_laptop
156: data:
157: message: "{{ message }}"
158:
159: # Fallback to secondary devices if primary unavailable
160: else:
161: - repeat:
162: for_each: "{{ v_fallback_devices }}"
163: sequence:
164: - if:
165: - condition: state
166: entity_id: "device_tracker.danny_{{ repeat.item|regex_replace('notify.danny_(.*)','\\1') }}"
167: state: "home"
168: - condition: numeric_state
169: entity_id: "sensor.danny_{{ repeat.item|regex_replace('notify.danny_(.*)','\\1') }}_battery"
170: above: 10
171: then:
172: - action: "{{ repeat.item }}"
173: data:
174: message: "{{ message }}"
Device Priority Chain:
Work Hours (09:00-17:00)
Primary: Laptop (battery > 20%)
↓
Fallback 1: Phone (battery > 10%)
↓
Fallback 2: Smartwatch (battery > 5%)
↓
Fallback 3: Send to all available
Evening (19:00-23:00)
Primary: Phone (battery > 10%)
↓
Fallback 1: Laptop (battery > 20%)
↓
Fallback 2: Smartwatch (battery > 5%)
↓
Fallback 3: Send to all available
Night/Other
Primary: Smartwatch (battery > 5%)
↓
Fallback 1: Phone (battery > 10%)
↓
Fallback 2: Send to all available
Configuration Required:
- All items from Approach A (time-based config)
- All items from Approach B (device tracking)
- Device priority matrices per time period
- Battery thresholds per device type
Behavior Example: Energy Alert at 14:30
Alert: "Solar production exceeding 3kW"
Person: Danny
Time: 14:30 (Tuesday, work hours)
Approach A (Context-Based)
- Check time: 14:30 → work hours
- Primary device: laptop
- Send to laptop only
- Danny sees alert immediately (working at laptop)
Approach B (Availability-Based)
- Check laptop: online, battery 75% ✅
- Send to laptop
- If offline: fallback to phone, smartwatch, or all devices
- Handles unexpected scenarios (working from coffee shop, forgot laptop)
Approach C (Hybrid)
- Check time: 14:30 → work hours
- Primary device: laptop
- Check laptop availability: online, battery 75% ✅
- Send to laptop
- If laptop offline: check phone (battery 45% ✅) → send there
- If both offline: smartwatch (battery 8% ✅) → send there
- If all offline: send to all available devices
Implementation Steps (For Future)
Phase 1: Approach A (Time-Based)
Phase 2: Approach B (Availability-Based)
Phase 3: Approach C (Hybrid)
Data Points Required
For Time-Based (Approach A)
input_datetime:
danny_work_start:
name: "Danny Work Start Time"
initial: "09:00:00"
danny_work_end:
name: "Danny Work End Time"
initial: "17:00:00"
danny_morning_start:
name: "Danny Morning Time"
initial: "07:00:00"
danny_evening_start:
name: "Danny Evening Time"
initial: "19:00:00"
danny_night_end:
name: "Danny Night End Time"
initial: "23:00:00"
input_select:
danny_work_hours_device:
name: "Danny Work Hours Device"
options:
- "laptop"
- "phone"
- "smartwatch"
initial: "laptop"
For Availability-Based (Approach B)
device_tracker:
danny_laptop:
name: "Danny Laptop"
unique_id: danny_laptop_tracker
danny_phone:
name: "Danny Phone"
unique_id: danny_phone_tracker
sensor:
danny_laptop_battery:
name: "Danny Laptop Battery"
unit_of_measurement: "%"
danny_phone_battery:
name: "Danny Phone Battery"
unit_of_measurement: "%"
Related Issues & PRs
Acceptance Criteria
Labels
enhancement, notifications, phase-3, device-routing
Summary
Implement intelligent device routing for notifications so messages are sent to the device a person is most likely to have with them, based on time of day, location, and device availability.
Motivation
Currently, notifications are sent to all devices simultaneously. This causes:
A smarter routing system would:
Implementation Approaches
Approach A: Context-Based (Time + Location)
Route based on time of day and person's location
Pros:
Cons:
Example Logic:
Behavior Examples:
Configuration Required:
Approach B: Availability-Based (Device State)
Route based on actual device availability: online status, battery level, last seen
Pros:
Cons:
Example Logic:
Behavior Examples:
Configuration Required:
Approach C: Hybrid (Context + Availability) ⭐ Recommended
Combine time-based context routing with availability fallback for best results
Pros:
Cons:
Example Logic:
Device Priority Chain:
Configuration Required:
Behavior Example: Energy Alert at 14:30
Alert: "Solar production exceeding 3kW"
Person: Danny
Time: 14:30 (Tuesday, work hours)
Approach A (Context-Based)
Approach B (Availability-Based)
Approach C (Hybrid)
Implementation Steps (For Future)
Phase 1: Approach A (Time-Based)
Phase 2: Approach B (Availability-Based)
Phase 3: Approach C (Hybrid)
Data Points Required
For Time-Based (Approach A)
For Availability-Based (Approach B)
Related Issues & PRs
Acceptance Criteria
Labels
enhancement, notifications, phase-3, device-routing