Controlling lights with both motion sensors and smart switches (optional light threshold)

The scope of the package is to be able to control lights with both motion sensors and smart switches (optional: light threshold depending on sun component or sensor can be applied).

Also, this should help improving electricity waste as lights will turn off even if the person exiting the room forgot to turn them off; although there’s a trade off between convenience (having the lights if someone is in the room) and efficiency (turn lights off when not needed), adding a motion sensor can improve on both.

The full setup is made of a room_name package and a global_settings package. If not familiar with packages see https://www.home-assistant.io/docs/configuration/packages/

In order to set for multiple rooms duplicate the room_name_package for each room, rename the package and its variables to the relevant values (global_settings_package contains only variables applicable to the entire house thus it doesn’t need significant changes) or use part of the automations as considered suitable.

I tried to comment most of the components in order to explain their usage and, mostly, their purpose. Feel free to criticize if I haven’t done a good job on all of them (not a software developer by any means so it is kind of difficult to “feel” the ideal amount of commenting).

Main functionalities:

  • control lights from both motion sensors (PIR or microwave) and smart switches without flickering when the active controlling unit changes;
  • have multiple motion sensors controlling the lights (case of non-standard form rooms such as L or T-shape where a single motion sensor is not sufficient to cover the entire space) with a resetable script and/or turn the lights on if insufficient light (in combination with a light sensor and/or sun component); also, set multiple way (2 way/3 way/n way) switches - “hotel like switching”;
  • modular setup, if no PIR available (motion sensor specific areas are indicated);
  • can use threshold for light (either sun dependent or measured with light sensor; I use a LDR attached to NodeMCU running OpenMQTTGateway https://github.com/1technophile/OpenMQTTGateway);
  • override switch for blocking motion sensor (and use only smart switches for controlling lights); this also can allow using motion sensors for alarm triggering only;
  • light platform independent (there are some MiLight specific components but they’re commented) and switch/motion sensor agnostic;
  • separate settings for RGB vs. CCT lights;
  • there are different timers based on the method of turning the lights on (lower timer value if lights are triggered by motion sensor vs. a higher timer value if triggered by switch);
  • case timer set for switch is near end and the motion sensor is triggered (or the timer for the switch is lower than the timer for motion sensor), then the control for the lights is transferred to motion sensor (via resetable script so that each time motion sensor is triggered the light will be set to the value of the timer);
  • all lights are set to brightness 1 before turning off (most smart lights turn on with the previous settings used before off in order to be able to use with “dumb” switches; Philips has sometimes recently added a feature to turn lights on with defined settings but most of the other type of smart lights use the last known settings); having brightness at 1 before sending other commands to lights ensures both smoother transitions and keeps inconveniences associated with power failures at minimum (otherwise lights could turn on at previous known settings in the middle of the night);
  • each individual value for R, G and B is based on input_number (there are several Python solutions that can be used for storing variables but input_number is still easy to use); the sliders for R, G and B can be controlled separately from other automations and can have multiple uses:
    • controlling all lights in the house in one move (in my case with MiLight groups) by forwarding color changes to the Group ID that is paired to all the lights in the house and changing individual R, G, B components that are used when the lights are turned on rather than turning the lights on (and annoying anyone who’s sleeping). If wanting to change multiple (turned on) lights it can be achieved either by changing them individually or changing the group defined in HA; the problem is that for more than 3-4 lights, on relatively under powered hosts such as Rpis, it would take near 10 seconds to change the values for all the entities in the group. In my case I used native groups of lights (outside HA) which would turn the lights on/off or change the colors in a single step;
    • set different lights color based on time of day (morning/day/sunset/night - these settings are not included in the package but I can provide them if interested) or through Circadian Lighting: https://community.home-assistant.io/t/circadian-lighting-custom-component/61246;
    • set different accents for Halloween, Christmas or warmer/colder lights during winter/summer (separate or in combination with the above);

Although it would be equally easy to use an input_boolean instead of a MQTT, the MQTT topics can be easily accessed from another system (either Home Assistant or OH, Domotic(x)).

While the switch will toggle the lights, the functionality of the motion sensor is summarized below (probably it would have been preferable a NodeRed flow; however, I started using Home Assistant prior to its introduction and I feel comfortable writing automations).

room_name_package
homeassistant:
sensor:
#ldr#  - platform: mqtt  
#ldr#    state_topic: 'home/room_name/adctomqtt'
#ldr#    name: 'sensor_ldr_room_name'  
#ldr#    unit_of_measurement: 'lux'
#ldr#    value_template: '{{ 1024 - value | float }}'
# Uncomment '#ldr#' to use the light sensor in the package 

input_number:
  room_name_light_sensitivity:
    name: 'room_name_light_sensitivity'
    min: 100
    max: 1000
    step: 50
    initial: 200
    mode: slider


#binary_sensor:
#Define binary_sensor here based on the specific configuration. 

switch:
#PIR override switch; 

  - platform: mqtt
    name: "switch_pir_override_room_name"
    state_topic: "home/room_name/pir_override/state"
    command_topic: "home/room_name/pir_override"
    payload_on: "on"
    payload_off: "off"
    optimistic: true
    qos: 0
    retain: true

#Switch lights; although use of a virtual switch to keep track of the physical devices is not mandatory, it simplifies control (as it centralizes all physical switches and can be used in the frontend to simultaneously turn the light on and set the timer).

  - platform: mqtt
    name: "switch_lights_room_name"
    state_topic: "home/room_name/lights_control/state"
    command_topic: "home/room_name/lights_control"
    payload_on: "on"
    payload_off: "off"
    optimistic: true
    qos: 0
    retain: true

#Switch color_temp in order to use color temperature mode for bulbs (if supported)

  - platform: mqtt
    name: "color_temp_room_name"
    state_topic: "home/room_name/color_temp/state"
    command_topic: "home/room_name/color_temp"
    payload_on: "on"
    payload_off: "off"
    optimistic: true
    qos: 0
    retain: true

script:

# General script
## Turns off all running scripts; sets brightness to 1 then turns the light off
  lights_off_room_name:
    sequence:
      - service: script.turn_off
        entity_id: script.timer_off_sw_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_switch_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_switch_room_name
#start of PIR section; comment following if not using PIR
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_pir_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_pir_room_name
#end of PIR section
      - service: light.turn_on
        data:
          entity_id: light.light_room_name
          brightness: 1
      - delay:
          milliseconds: 100
      - service: light.turn_off
        entity_id: light.light_room_name

# Timers scripts (use the value of the input number to schedule lights off)
##1. Timer to turn lights off when switch was used (use the value of the input_number to schedule lights off)
  timer_off_sw_room_name:
    sequence:
      - service: script.turn_off
        entity_id: script.lights_off_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_switch_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_switch_room_name
#start of PIR section; comment following if not using PIR
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_pir_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_pir_room_name
#end of PIR section
# switch will turn off the lights regardless if PIR or switch turned them on initially
      - delay: '{{(states.input_number.switch_timer.state|int/60)|int}}:{{(states.input_number.switch_timer.state | int)%60 }}:00'
      - service: switch.turn_off
        entity_id: switch.switch_lights_room_name

##2. Timer to turn lights off when PIR was used (use the value of the input number to schedule lights off)
#Comment if not using PIR
  timer_off_pir_room_name:
    sequence:
      - delay: '{{(states.input_number.pir_timer.state|int/60)|int}}:{{(states.input_number.pir_timer.state | int)%60 }}:00'
      - service: script.turn_on
        entity_id: script.lights_off_room_name

##3.a. Timer when switch was used in CT mode
  timer_ct_switch_room_name:
    sequence:
      - service: light.turn_on
        data_template:
          effect: "white_mode"
          entity_id: light.light_room_name
          brightness: '{{ states.input_number.dimmer.state | int }}'
          color_temp: '{{ states.input_number.color.state | int }}'
      - service: script.turn_on
        entity_id: script.timer_off_sw_room_name

##3.b. Timer when switch was used in RGB mode
  timer_rgb_switch_room_name:
    sequence:
      - service: light.turn_on
        data_template:
          entity_id: light.light_room_name
          brightness: '{{ states.input_number.dimmer.state | int }}'
          rgb_color: ['{{states.input_number.r.state | int}}','{{states.input_number.g.state | int}}','{{states.input_number.b.state | int}}']
      - service: script.turn_on
        entity_id: script.timer_off_sw_room_name

##4.a. Timer for PIR in CT mode
#Comment if not using PIR
  timer_ct_pir_room_name:
    sequence:
# Cancel old timer
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: light.turn_on
        data_template:
          effect: "white_mode"
          entity_id: light.light_room_name
          brightness: '{{ states.input_number.dimmer.state | int }}'
          color_temp: '{{ states.input_number.color.state | int }}'
# Set new timer
      - service: script.turn_on
        entity_id: script.timer_off_pir_room_name

##4.b. Timer for PIR in RGB mode
#Comment if not using PIR
  timer_rgb_pir_room_name:
    sequence:
# Cancel old timer
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: light.turn_on
        data_template:
          entity_id: light.light_room_name
          brightness: '{{ states.input_number.dimmer.state | int }}'
          rgb_color: ['{{states.input_number.r.state | int}}','{{states.input_number.g.state | int}}','{{states.input_number.b.state | int}}']
# Set new timer
      - service: script.turn_on
        entity_id: script.timer_off_pir_room_name

automation:

# MiLight specific: Send turn off to lights that are already off (case previous off command didn't reached the bulb)

#milight_specific#  - alias: room_name lights set to off
#milight_specific#    initial_state: 'on'
#milight_specific#    trigger: 
#milight_specific#      - platform: time_pattern
#milight_specific#        minutes: '/5'
#milight_specific#        seconds: 17
#milight_specific#    condition:
#milight_specific#      condition: and
#milight_specific#      conditions:
#milight_specific#        - condition: state
#milight_specific#          entity_id: light.light_room_name
#milight_specific#          state: 'off'
#milight_specific#    action:
#milight_specific#      - service: mqtt.publish
#milight_specific#        data:
#milight_specific#          topic: "milight_gw/0x2/rgb_cct/4"
#milight_specific#          payload: '{"state":"off"}'

# Turn off lights if both lights and switch are on
  - alias: room_name turn off lights
    initial_state: 'on'
    trigger:
#Replace with own defined binary_sensor/sensor/switch
      - platform: state
        entity_id: binary_sensor.binary_sensor_switch_1_room_name, binary_sensor.binary_sensor_switch_2_room_name, binary_sensor.binary_sensor_switch_3_room_name
        to: 'on'
      - platform: state
        entity_id: sensor.sensor_switch_1_room_name, sensor.sensor_switch_2_room_name, sensor.sensor_switch_3_room_name
        to: 'single'
      - platform: state
        entity_id: switch.switch_1_room_name, switch.switch_2_room_name, switch.switch_3_room_name
#The multiple entities used for trigger achieve the 3way switching; the number of physical switches that can be used here is not limited. Pressing any of the switches will toggle the light regardless of the switch that was used before.
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
#The switch used here is virtual, not tied to any hardware switch;
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'on'
    action:
      - service: switch.turn_off
        entity_id: switch.switch_lights_room_name

  - alias: room_name turn off lights if lights are on and switch is off
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_switch_1_room_name, binary_sensor.binary_sensor_switch_2_room_name, binary_sensor.binary_sensor_switch_3_room_name
        to: 'on'
      - platform: state
        entity_id: sensor.sensor_switch_1_room_name, sensor.sensor_switch_2_room_name, sensor.sensor_switch_3_room_name
        to: 'single'
      - platform: state
        entity_id: switch.switch_1_room_name, switch.switch_2_room_name, switch.switch_3_room_name
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'off'
    action:
      - service: script.turn_on
        entity_id: script.lights_off_room_name

  - alias: room_name turn on lights if both lights and switch are off
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_switch_1_room_name, binary_sensor.binary_sensor_switch_2_room_name, binary_sensor.binary_sensor_switch_3_room_name
        to: 'on'
      - platform: state
        entity_id: sensor.sensor_switch_1_room_name, sensor.sensor_switch_2_room_name, sensor.sensor_switch_3_room_name
        to: 'single'
      - platform: state
        entity_id: switch.switch_1_room_name, switch.switch_2_room_name, switch.switch_3_room_name
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'off'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'off'
    action:
      - service: switch.turn_on
        entity_id: switch.switch_lights_room_name

  - alias: room_name turn on lights if switch is already on in CT mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_switch_1_room_name, binary_sensor.binary_sensor_switch_2_room_name, binary_sensor.binary_sensor_switch_3_room_name
        to: 'on'
      - platform: state
        entity_id: sensor.sensor_switch_1_room_name, sensor.sensor_switch_2_room_name, sensor.sensor_switch_3_room_name
        to: 'single'
      - platform: state
        entity_id: switch.switch_1_room_name, switch.switch_2_room_name, switch.switch_3_room_name
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'off'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'on'
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'on'
    action:
      - service: script.turn_on
        entity_id: script.timer_ct_switch_room_name

  - alias: room_name turn on lights if switch is already on in RGB mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_switch_1_room_name, binary_sensor.binary_sensor_switch_2_room_name, binary_sensor.binary_sensor_switch_3_room_name
        to: 'on'
      - platform: state
        entity_id: sensor.sensor_switch_1_room_name, sensor.sensor_switch_2_room_name, sensor.sensor_switch_3_room_name
        to: 'single'
      - platform: state
        entity_id: switch.switch_1_room_name, switch.switch_2_room_name, switch.switch_3_room_name
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'off'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'on'
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'off'
    action:
      - service: script.turn_on
        entity_id: script.timer_rgb_switch_room_name

##Switch turns on lights and sets delay to PIR timer if switch timer is lower than PIR timer
  - alias: room_name turn switch to PIR timer in CT mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: switch.switch_lights_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'on'
        - condition: template
          value_template: '{{(states.input_number.switch_timer.state) | int < (states.input_number.pir_timer.state| int)}}'
    action:
        - service: script.turn_on
          entity_id: script.timer_ct_pir_room_name

  - alias: room_name turn switch to PIR timer in RGB mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: switch.switch_lights_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'off'
        - condition: template
          value_template: '{{(states.input_number.switch_timer.state) | int < (states.input_number.pir_timer.state| int)}}'
    action:
        - service: script.turn_on
          entity_id: script.timer_rgb_pir_room_name

#Switch timer set
  - alias: room_name switch timer in CT mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: switch.switch_lights_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'on'
    action:
      - service: script.turn_on
        entity_id: script.timer_ct_switch_room_name

  - alias: room_name switch timer in CT mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: switch.switch_lights_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'off'
    action:
      - service: script.turn_on
        entity_id: script.timer_rgb_switch_room_name

#Turn on lights if PIR sensor is triggered and lights are off
#Comment if not using PIR
  - alias: room_name PIR trigger in CT mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_pir_1_room_name, binary_sensor.binary_sensor_pir_2_room_name, binary_sensor.binary_sensor_pir_3_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'off'
        - condition: or
          conditions:
            - condition: state
              entity_id: sun.sun
              state: 'below_horizon'
#ldr#            - condition: template
#ldr#              value_template: '{{(states.sensor.sensor_ldr_room_name.state | int) < (states.input_number.room_name_light_sensitivity.state | int)}}'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'on'
    action:
      - service: script.turn_on
        entity_id: script.timer_ct_pir_room_name

  - alias: room_name PIR trigger in RGB mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_pir_1_room_name, binary_sensor.binary_sensor_pir_2_room_name, binary_sensor.binary_sensor_pir_3_room_name
        to: 'on'
#These binary sensors correspond to Kerui P819 physical PIR sensors. Any number of PIR sensors can be used as trigger (suitable for large rooms or non-standard form rooms where a single PIR cannot cover the entire surface or turning the lights only in a designated area - ie. by waiving hand below/above the bed).
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'off'
        - condition: or
          conditions:
            - condition: state
              entity_id: sun.sun
              state: 'below_horizon'
#ldr#            - condition: template
#ldr#             value_template: '{{(states.sensor.sensor_ldr_room_name.state | int) < (states.input_number.room_name_light_sensitivity.state | int)}}'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'
#By overriding the PIR function only switches (or HA) can turn the lights on.
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'off'
    action:
      - service: script.turn_on
        entity_id: script.timer_rgb_pir_room_name

#Send turn on again (case one of the bulbs didn't turn on properly)
#Comment if not using PIR
  - alias: room_name pir trigger if insufficient brightness in CT mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_pir_1_room_name, binary_sensor.binary_sensor_pir_2_room_name, binary_sensor.binary_sensor_pir_3_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'off'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'on'
#ldr#        - condition: template
#ldr#          value_template: '{{(states.sensor.sensor_ldr_room_name.state | int) < (states.input_number.room_name_light_sensitivity.state | int)}}'
    action:
      - service: script.turn_on
        entity_id: script.timer_ct_pir_room_name

#Comment if not using PIR
  - alias: room_name pir trigger if insufficient brightness in RGB mode
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_pir_1_room_name, binary_sensor.binary_sensor_pir_2_room_name, binary_sensor.binary_sensor_pir_3_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'off'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'
        - condition: state
          entity_id: switch.color_temp_room_name
          state: 'off'
#ldr#        - condition: template
#ldr#          value_template: '{{(states.sensor.sensor_ldr_room_name.state | int) < (states.input_number.room_name_light_sensitivity.state | int)}}'
    action:
      - service: script.turn_on
        entity_id: script.timer_rgb_pir_room_name

#E.2 Keep lights on if PIR sensor is triggered and lights are on (triggered by SWITCH - then PIR takes over)
#Comment if not using PIR
  - alias: room_name switch triggers pir takes over
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_pir_1_room_name, binary_sensor.binary_sensor_pir_2_room_name, binary_sensor.binary_sensor_pir_3_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'on'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'
        - condition: template
          value_template: '{{(states.input_number.switch_timer.state | int - (as_timestamp(now())-as_timestamp(states.light.light_room_name.last_changed))/60) < (states.input_number.pir_timer.state| int)}}'
    action:
      - service: script.turn_off
        entity_id: script.timer_off_sw_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_switch_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_switch_room_name
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: script.turn_on
        entity_id: script.timer_off_pir_room_name

#F.1 Keep lights on if PIR sensor is triggered and lights are on (previously triggered by PIR)
#Comment if not using PIR
  - alias: room_name pir sensor trigger again
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: binary_sensor.binary_sensor_pir_1_room_name, binary_sensor.binary_sensor_pir_2_room_name, binary_sensor.binary_sensor_pir_3_room_name
        to: 'on'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
        - condition: state
          entity_id: switch.switch_lights_room_name
          state: 'off'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'
    action:
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: script.turn_on
        entity_id: script.timer_off_pir_room_name

#Turn off lights
  - alias: room_name turn off lights
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: switch.switch_lights_room_name
        to: 'off'
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: light.light_room_name
          state: 'on'
    action:
      - service: script.turn_on
        entity_id: script.lights_off_room_name

# Terminate all scripts if light is turned off
  - alias: room_name turn off scripts if lights are off
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: light.light_room_name
        to: 'off'
    action:
      - service: script.turn_off
        entity_id: script.lights_off_room_name
      - service: script.turn_off
        entity_id: script.timer_off_sw_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_switch_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_switch_room_name
#start of PIR section; comment following if not using PIR
      - service: script.turn_off
        entity_id: script.timer_off_pir_room_name
      - service: script.turn_off
        entity_id: script.timer_ct_pir_room_name
      - service: script.turn_off
        entity_id: script.timer_rgb_pir_room_name
#end of PIR section
general_settings_package
homeassistant:

input_number:
  dimmer:
    name: 'Dimmer'
    min: 0
    max: 255
    step: 15
    mode: slider
  color:
    name: 'Color Temp'
    min: 0
    max: 370
    step: 10
    mode: slider
  r:
    name: 'Red'
    min: 0
    max: 255
    step: 15
    mode: slider
  g: 
    name: 'Green'
    min: 0
    max: 255
    step: 15
    mode: slider
  b: 
    name: 'Blue'
    min: 0
    max: 255
    step: 15
    mode: slider
  pir_timer:
    name: 'PIR Timer'
    min: 1
#defines timer for lights if triggerred by PIR sensor; change max and initial as suitable
    max: 61
    step: 5
    initial: 11
    mode: slider
  switch_timer:
    name: 'Switch Timer'
    min: 1
#defines timer for lights if triggerred by switch sensor; change max and initial as suitable
    max: 121
    step: 12
    initial: 37
    mode: slider
2 Likes

Thank you for sharing this. Very interesting.
I’m struggling to workout where do I insert the real/existing switch. Let’s say the room has 2 lights; light.ceiling and light.lamp.

It depends on how you want the lights to be controlled:

  • if both ceiling and lamp should turn on the same time then you can create a light group in HA and search&replace light.light_room_name with that light group name in the entire package instead of including both lights in the respective sections of the package; however, I think that a better way of turning multiple lights on and off is to have the lights group created outside HA (at least the products I use, Philips Hue and MiLight can do this) as with HA light groups it would take somewhere from half of a second to 2 seconds to turn all the lights in the group and I found this annoying. However, if a certain delay in turning lights on and off is acceptable, then the light group in HA is fine.
  • if only one of the lights need to turn with the motion sensor (ie. ceiling) then replace light.light_room_name with that respective light name.

I hope that, eventually, with the developing of the native scheduling, this kind of functionality will be included as standard in HA as it can be developed into a component and only have a GUI that would allow to:

  • define a room that would have the logic defined for triggering lights on and off (basically motion sensors turns the lights on if the light level is low or can override if the remaining timer is below the nominal value and the switch would toggle the lights);
  • associate several existing sensors as the motion triggering in that particular room;
  • define several switches as the ones that should control lights;
  • define a light level sensor;
  • define custom triggers for the lights, independent of the motion and switches (such as at sunset/sunrise with a certain offset, hourly, randomly, during a certain period when house is unoccupied, etc.)
  • optional: associate several open door sensors (this is a little bit tricky as it needs to know what was the previous occupied room)

Then, the user would only need to manually set the duration for each type of schedule (in my package is set with input_number differently for motion sensor vs. switch) or an override for the motion sensor.

As a side note, instead of overriding in HA, a LDR can be added to a motion sensor so that it would trigger only when the light level is below a certain threshold, but this means (alongside with required soldering skills) that the motion sensor cannot be used all the time with the alarm as it would trigger only during the low light periods.

Thank you for your prompt response and detailed explanation.
Much appreciated

Edit: sorry another question; as i understand it the lights would turn on based on pir or switch.
There’s now daytime condition; for example after sunset or similar.

I believe you are personally using a light sensor?

Hi,

Haven’t seen the later edit.

The light sensor I use is a simple LDR connected to analog pin of a NodeMCU.

I have the sun component (below_horizon) in my automation but would work also with elevation.

  condition: template  
  value_template: "{{ state_attr('sun.sun', 'elevation') < -3 }}"
        - condition: or
          conditions:
            - condition: state
              entity_id: sun.sun
              state: 'below_horizon'
#ldr#            - condition: template
#ldr#             value_template: '{{(states.sensor.sensor_ldr_room_name.state | int) < (states.input_number.room_name_light_sensitivity.state | int)}}'
        - condition: state
          entity_id: switch.switch_pir_override_room_name
          state: 'off'

Thank you for your response