Wow!
This appdaemon app just made my whole setup so much sleeker! I noticed this a while ago but couldn’t wrap my mind around how it would cater to my needs, so I started building my own solution (for appdaemon). While building I felt like I needed to check this out again too see if it would save me some time and it did!
For now I’ve automated all my lights both by using time, lux and motion inputs. I’ve also managed to make some custom schedules for the livingroom to turn off lights when a movie is started.
The scheduling part is really dynamic! The only thing i’m missing is a way for the schedules to turn on for a limited time when motion happens. But I solved this by adding custom binary sensors of my real motion sensor that turns off only when the real sensor has been off for 2-3 minutes.
Leaving my current configuration if anyone wonders what it looks like or maybe someone have an idéa of how I could improve it.
schedy_lights:
module: hass_apps_loader
class: SchedyApp
debug: false
actor_type: generic
actor_templates:
default:
template: light
light:
attributes:
- attribute: state
values:
"on":
service: light.turn_on
service_data: {}
include_entity_id: true
value_parameter: null
"off":
service: light.turn_off
service_data: {}
include_entity_id: true
value_parameter: null
- attribute: brightness_pct
values:
"_other_":
service: light.turn_on
service_data: {}
include_entity_id: true
value_parameter: brightness_pct
short_values:
- ['off']
- ['on', '_other_']
send_retries: 1
switch:
attributes:
- attribute: state
values:
"on":
service: switch.turn_on
service_data: {}
include_entity_id: true
value_parameter: null
"off":
service: switch.turn_off
service_data: {}
include_entity_id: true
value_parameter: null
short_values:
- ['off']
- ['on']
send_retries: 1
schedule_append:
- v: 'off'
schedule_snippets:
motion:
- v: ['on', 85]
start: '07:00'
end: '23:30'
rules:
- x: "Next() if float(state(next(x for x in filter_entities('sensor', lux_room=room_name)))) < 6 else Break()"
- x: "Next() if not is_empty(filter_entities('binary_sensor', motion_room=room_name, state='on')) else Break()"
- x: "Inherit()"
- v: ['on', 35]
start: '23:30'
end: '07:00'
rules:
- x: "Next() if float(state(next(x for x in filter_entities('sensor', lux_room=room_name)))) < 4 else Break()"
- x: "Next() if not is_empty(filter_entities('binary_sensor', motion_room=room_name, state='on')) else Break()"
- x: "Inherit()"
outdoor_home_north:
- v: 'on'
rules:
- { x: "Next() if state('group.family') == 'home' else Break()" }
- { x: "Next() if float(state('sensor.zigbee_006_lux')) < 45 else Break()" }
- { v: ['on', 75], start: '08:00', end: '21:00' }
- { v: ['on', 10], start: '21:00', end: '08:00' }
outdoor_home_south:
- v: 'on'
rules:
- { x: "Next() if state('group.family') == 'home' else Break()" }
- { x: "Next() if float(state('sensor.zigbee_006_lux')) < 45 else Break()" }
- { v: ['on', 75], start: '08:00', end: '18:00' }
- { v: ['on', 5], start: '18:00', end: '08:00' }
outdoor_not_home:
- v: 'on'
rules:
- { x: "Next() if state('group.family') == 'not_home' else Break()" }
- { x: "Next() if float(state('sensor.zigbee_006_lux')) < 45 else Break()" }
- { v: ['on', 75], start: '08:00', end: '21:00' }
- { v: ['on', 40], start: '21:00', end: '08:00' }
indoor_home:
- v: 'on'
rules:
- { x: "Next() if state('group.family') == 'home' else Break()" }
- { x: "Next() if float(state('sensor.zigbee_006_lux')) < 95 else Break()" }
- { v: ['on', 85], start: '15:00', end: '20:00' }
- { v: ['on', 65], start: '20:00', end: '23:30' }
- { v: ['on', 75], start: '08:00', end: '10:00', weekdays: 1-7 }
- { v: ['on', 65], start: '06:45', end: '08:00', weekdays: 1-5 }
bedroom_home:
- v: 'on'
rules:
- { x: "Next() if state('group.family') == 'home' else Break()" }
- { x: "Next() if float(state('sensor.zigbee_006_lux')) < 95 else Break()" }
- { v: ['on', 85], start: '15:00', end: '18:00' }
- { v: ['on', 10], start: '18:00', end: '19:00' }
- { v: ['on', 75], start: '08:00', end: '10:00', weekdays: 1-7 }
livingroom_tv:
- v: 'off'
rules:
- { x: "Next() if state('media_player.livingroom_tv') == 'playing' else Break()" }
- { x: "Next() if state('media_player.livingroom_tv', 'media_content_type') == 'movie' else Break()" }
- { x: "Inherit()" }
rooms:
basementhall:
friendly_name: 'Kallarhallen'
allow_manual_changes: false
rescheduling_delay: 0
actors:
light.cellar_hallway_lights:
schedule:
- x: "IncludeSchedule(schedule_snippets['motion'])"
watched_entities:
- 'sensor.zigbee_008_lux:state:ignore'
- 'binary_sensor.zigbee_008_motion_timed'
bedroom:
friendly_name: 'Sovrum'
allow_manual_changes: true
rescheduling_delay: 210
actors:
light.masterbedroom_window_light:
schedule:
- x: "IncludeSchedule(schedule_snippets['bedroom_home'])"
garage:
friendly_name: 'Garage'
allow_manual_changes: true
rescheduling_delay: 60
actors:
switch.esphome_004_switch:
template: switch
schedule:
- x: "Postprocess(lambda result: (result[0]))"
- x: "IncludeSchedule(schedule_snippets['motion'])"
watched_entities:
- 'binary_sensor.zigbee_011_motion_timed'
- 'sensor.zigbee_011_lux:state:ignore'
gillestugan:
friendly_name: 'Gillestugan'
allow_manual_changes: true
rescheduling_delay: 60
actors:
light.gillestugan_lights:
schedule:
- x: "Postprocess(lambda result: (result[0], min(result[1], 35)) if result != 'off' else 'off')"
- x: "IncludeSchedule(schedule_snippets['motion'])"
- x: "IncludeSchedule(schedule_snippets['indoor_home'])"
watched_entities:
- 'binary_sensor.zigbee_003_motion_timed'
- 'sensor.zigbee_003_lux:state:ignore'
hallway:
friendly_name: 'Hallen'
allow_manual_changes: true
rescheduling_delay: 60
actors:
light.upper_hallway_lights:
schedule:
- x: "IncludeSchedule(schedule_snippets['motion'])"
- x: "IncludeSchedule(schedule_snippets['indoor_home'])"
watched_entities:
- 'binary_sensor.zigbee_009_motion_timed'
- 'sensor.zigbee_009_lux:state:ignore'
kitchen:
friendly_name: 'Koket'
allow_manual_changes: true
rescheduling_delay: 210
actors:
light.kitchen_window_lights:
schedule:
- v: ['on', 100]
start: '16:00'
end: '18:00'
months: 1-4, 9-12
rules:
- x: "Inherit() if state('group.family') == 'home' else Break()"
- x: "IncludeSchedule(schedule_snippets['indoor_home'])"
livingroom:
friendly_name: 'Vardagsrum'
allow_manual_changes: true
rescheduling_delay: 210
actors:
light.livingroom_wall_lights:
light.livingroom_window_lights:
schedule:
- x: "IncludeSchedule(schedule_snippets['livingroom_tv'])"
- x: "IncludeSchedule(schedule_snippets['motion'])"
- x: "IncludeSchedule(schedule_snippets['indoor_home'])"
watched_entities:
- 'binary_sensor.zigbee_010_motion_timed'
- 'sensor.zigbee_010_lux:state:ignore'
- 'media_player.livingroom_tv'
lucas:
friendly_name: 'Lucas'
allow_manual_changes: true
rescheduling_delay: 210
actors:
light.kid_room_window:
schedule:
- x: "IncludeSchedule(schedule_snippets['bedroom_home'])"
office:
friendly_name: 'Kontoret'
allow_manual_changes: true
rescheduling_delay: 60
actors:
light.office_table_light:
schedule:
- x: "IncludeSchedule(schedule_snippets['motion'])"
- x: "IncludeSchedule(schedule_snippets['indoor_home'])"
watched_entities:
- 'binary_sensor.zigbee_007_motion_timed'
- 'sensor.zigbee_007_lux:state:ignore'
outdoor_north:
friendly_name: 'Utomhus Norra'
allow_manual_changes: true
rescheduling_delay: 60
actors:
light.outdoor_north_side_lights:
schedule:
- x: "IncludeSchedule(schedule_snippets['outdoor_home_north'])"
- x: "IncludeSchedule(schedule_snippets['outdoor_not_home'])"
outdoor_south:
friendly_name: 'Utomhus Södra'
allow_manual_changes: true
rescheduling_delay: 60
actors:
light.outdoor_south_side_lights:
schedule:
- x: "IncludeSchedule(schedule_snippets['outdoor_home_south'])"
- x: "IncludeSchedule(schedule_snippets['outdoor_not_home'])"
watched_entities:
- 'sensor.zigbee_006_lux'
- 'group.family'