Need help with lighting automation

Hello everybody,
forgive me for missing info, stupid questions, a wall of text and maybe even using the wrong channel. I just ported my Domoticz@Synology z-wave network to hass.io on raspberry pi (Home Assistant 0.77.3) and already struggle with the basics. I read a lot of documentation and forum discussions from which I created the automation scripts further down below.
The configuration check runs well (does that mean formatting is allright?), but it doesn’t really do, what I want it to do. Here is what I intended:
I have four different z-wave wall plugs which I use as light switches. Three of them have the ‘switch’ property and one (the one with a built-in dimmer) has the ‘light’ property. I created a group entry like this:

  light_EG:
    name: Light_EG
    view: yes
    entities:
      - light.everspring_ad147_plugin_dimmer_module_level
      - switch.unknown_node_26_switch
      - switch.greenwave_powernode_1_port_switch
      - switch.unknown_node_14_switch

I do have troubles with switching the everspring ‘light’ node and also the devices are seperated within the group. I read something about a ‘light group’ which might help, allthough I don’t really understand how it works, but this might be something for another thread …
What I want it to do is the following:

  • between 6:30 and 23:00 I want all lights to turn on, if the luminance sensor reports a drop in brightness
  • during the same time all lights should be turned off if the luminance sensor reports brightening conditions
  • at 23:00 all lights should be switched off until next morning 6:30 (if there isn’t bright light outside then)
  • whent the movement sensor (which physically is the same Fibaro z-wave sensor) senses motion between 23:00 and 6:30, all lights should be switched on for five minutes
  • There should be a log message on every switching action

I don’t want the system being busy with rechecking every second if the conditions are met and I also don’t want it to switch back and forth too often. So is there a possibility to include in the trigger something like

from: above: '29'
to: below: '30'

and then ignore all changes for 15 minutes or so?

Finally, here come the scripts. I deliberately put in and-conditions so that adding conditions in the future is more convenient. I saw people putting the trigger once more into the conditions section, which I did here as well. Is this really needed? Or does it maybe even hurt?

EDIT: I updated the script throughout this thread. Please look at my latest post.

- alias: light.on.when.dark
  trigger:
  - platform: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    below: '30'
  - platform: time
    at: '06:30'
  condition:
  - condition: and
    conditions:
      - condition: time
        after: '06:30'
        before: '23:00'
      - condition: numeric_state
        entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
        below: '30'
  action:
    - service: switch.turn_on
      data:
        entity_id:
        - group.light_EG
    - service: persistent_notification.create
      data:
        message: 'Light has been switched on because of fading light.'


- alias: light.off.when.bright
  trigger:
  - platform: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    above: '35'
  condition:
  - condition: and
    conditions:
      - condition: time
        after: '06:30'
        before: '23:00'
      - condition: numeric_state
        entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
        above: '35'
  action:
    - service: switch.turn_off
      data:
        entity_id:
        - group.light_EG
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off because of enough brightness.'
        


- alias: light.off.at.night
  trigger:
  - platform: time
    at: '23:00'
  action:
    - service: switch.turn_off
      data:
        entity_id:
        - group.light_EG
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off because it is late.'
        

- alias: light.on.when.nightly.movement
  trigger:
  - platform: state
    entity_id: 'binary_sensor.fibaro_system_fgms001zw5_motion_sensor_sensor'
    from: 'off'
    to: 'on'
  condition:
  - condition: and
    conditions:
      - condition: time
        after: '23:00'
        before: '06:25'
  action:
    - service: switch.turn_on
      data:
        entity_id:
        - group.light_EG
    - service: persistent_notification.create
      data:
        message: 'Light has been switched on for five minutes because of movement during the night.'

What the scripts actually do is turning on the light constantly (allthough I changed a lot without longer testing recently).
Thanks for reading until here and thanks for being patient with a beginner. Looking forward to your suggestions.

I’ll provide some more feedback next, but the main issue you have is you’re using the switch.turn_on and switch.turn_off services but giving it a group which is a mix of switches and lights. In this scenario, you should use the homeassistant.turn_on and homeassistant.turn_off service (which will work with a mix of “domains”, as they are called in HA.)

1 Like

Ok, thanks! Will switch to “homeassistant.turn” immediately.
You are right, it really only turns on the switches. However I would still expect it to work with only the switches, which it somehow doesn’t (or at least not as intended).

You’ve come to the right place. :slight_smile: And there are no stupid questions; HA takes a bit of getting used to. :wink:

A light group is a special light entity that can only contain other light entities. It’s kind of a hybrid between a group and a light. It makes a collection of lights appear to be a single light. I suppose it has its uses, but personally I don’t use them. And, in your situation, you really can’t because you have a mix of switches and lights. A “regular” group is what you want.

In general automation triggers are only evaluated when the referenced entities change – i.e., “on demand.” And for a numeric_state trigger, it will only “fire” when a threshold is crossed (except at startup, which is a special case.) So, e.g., with your light.on.when.dark automation, it will only trigger when sensor.fibaro_system_fgms001zw5_motion_sensor_luminance’s state, evaluated as a number, goes from a value 30 or above to a value below 30. Specifically, it won’t trigger when it goes from, say, 29 to 28, or 28 to 26, …

That’s the default. So:

  condition:
  - condition: and
    conditions:
      - condition: time
        after: '06:30'
        before: '23:00'
      - condition: numeric_state
        entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
        below: '30'

is the same as:

  condition:
  - condition: time
    after: '06:30'
    before: '23:00'
  - condition: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    below: '30'

For a service, there is a shortcut to entity_id. I.e.:

  - service: xxx.yyy
    data:
        entity_id:
          - aaa.bbb

is the same as:

  - service: xxx.yyy
    entity_id: aaa.bbb

Hope this helps. Don’t hesitate to ask if you have more questions.

1 Like

Sorry, I don’t understand. Maybe there were some typos in that reply???

Basically, to turn on a group of entities, where some are switches, and some are lights, would be done like this:

  - service: homeassistant.turn_on
    entity_id: group.light_EG

BTW, generally entity_id’s should be all lower case.

Sorry for that. I edited the former post for easier reading (I hope). All I wanted to say is that I would still have expected the switches (not the ‘light’ entity) to work as intended by using the switch.turn commands.

I took in your advice, which really helped making it easier to read. This is what it looks like now:

- alias: light.on.when.dark
  trigger:
  - platform: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    below: '30'
  - platform: time
    at: '06:30'
  condition:
  - condition: time
    after: '06:30'
    before: '23:00'
  - condition: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    below: '30'
  action:
    - service: homeassistant.turn_on
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched on because of fading light.'


- alias: light.off.when.bright
  trigger:
  - platform: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    above: '35'
  condition:
  - condition: time
    after: '06:30'
    before: '23:00'
  - condition: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    above: '35'
  action:
    - service: homeassistant.turn_off
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off because of enough brightness.'
        


- alias: light.off.at.night
  trigger:
  - platform: time
    at: '23:00'
  action:
    - service: homeassistant.turn_off
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off because it is late.'
        

- alias: light.on.when.nightly.movement
  trigger:
  - platform: state
    entity_id: 'binary_sensor.fibaro_system_fgms001zw5_motion_sensor_sensor'
    from: 'off'
    to: 'on'
  condition:
  - condition: time
    after: '23:00'
    before: '06:25'
  action:
    - service: homeassistant.turn_on
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched on for five minutes because of movement during the night.'

The scripts also for once seemed to work as intended during the last ten minutes. I won’t be at home for two days but will let them run and come back with the results afterwards. If anybody has some more code and algorithm optimization advices, I would be happy to learn.
Once more, thanks!

Two more suggestions:

First, your last automation turns the lights on during the night when there’s movement, but it doesn’t turn them back off after five minutes. Typically the lights are turned off after X minutes of no motion detection. The easiest way to do that is to add another automation that is triggered by:

  trigger:
  - platform: state
    entity_id: 'binary_sensor.fibaro_system_fgms001zw5_motion_sensor_sensor'
    to: 'off'
    for:
      minutes: 5

It should have the same condition that checks that it’s nighttime.

And lastly, everything looks good, except if HA restarts, and it misses a time period transition. I’d suggest adding the following trigger to your existing first and third automations:

  - platform: homeassistant
    event: start

And then to your third automation, add a condition that checks that it’s nighttime.

1 Like

Yep, forgot about asking that. Thanks! What exactly does the system with your code? Does it wait another five minutes after the trigger before checking conditions and taking actions, which is interupted, if the triggereing state changes again?

I also added it to the second, since it doesn’t trigger, once it is below the threshold, correct?

The code now looks like this:

- alias: light.on.when.dark
  trigger:
  - platform: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    below: '30'
  - platform: time
    at: '06:30'
  - platform: homeassistant
    event: start
  condition:
  - condition: time
    after: '06:29'
    before: '23:00'
  - condition: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    below: '30'
  action:
    - service: homeassistant.turn_on
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched on because of fading light.'


- alias: light.off.when.bright
  trigger:
  - platform: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    above: '35'
  - platform: homeassistant
    event: start
  condition:
  - condition: time
    after: '06:30'
    before: '23:00'
  - condition: numeric_state
    entity_id: 'sensor.fibaro_system_fgms001zw5_motion_sensor_luminance'
    above: '35'
  action:
    - service: homeassistant.turn_off
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off because of enough brightness.'
        


- alias: light.off.at.night
  trigger:
  - platform: time
    at: '23:00'
  - platform: homeassistant
    event: start
  condition:
  - condition: time
    after: '22:59'
    before: '06:30'
  action:
    - service: homeassistant.turn_off
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off because it is late.'
        

- alias: light.on.when.nightly.movement
  trigger:
  - platform: state
    entity_id: 'binary_sensor.fibaro_system_fgms001zw5_motion_sensor_sensor'
    from: 'off'
    to: 'on'
  condition:
  - condition: time
    after: '23:00'
    before: '06:30'
  action:
    - service: homeassistant.turn_on
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched on for five minutes because of movement during the night.'
        

- alias: light.off.after.five.minutes.at.night
  trigger:
  - platform: state
    entity_id: 'binary_sensor.fibaro_system_fgms001zw5_motion_sensor_sensor'
    to: 'off'
    for:
      minutes: 5
  condition:
  - condition: time
    after: '22:59'
    before: '06:30'
  action:
    - service: homeassistant.turn_off
      entity_id: group.light_eg
    - service: persistent_notification.create
      data:
        message: 'Light has been switched off after five minutes of no movement.'

It still is triggering.

23:13 [light.on.when.dark] has been triggered

allthough the condition states

before: '23:00'

What did I miss? Also, the motion sensor doesn’t trigger, but this might be due to using a wrong entity_id …
Sorry, but I need to go to bed now and won’t be back until Thursday. Switching scripts off for now.

When using for: the trigger is actually delayed. When the to: and/or for: is first met, the trigger effectively starts a timer. As long as the state doesn’t change, when the timer expires the trigger will “fire.” However, if the state changes during the time period, the trigger effectively “resets.” The automation’s conditions are not evaluated until the trigger actually fires.

So, this is where the “special case” I referred to comes into play. A numeric_state trigger usually only fires when the threshold is crossed. In the case of this automation, that means it will usually only trigger when the value goes from 35 or below to above 35. The special case is, when the entity changes state the first time after startup, if it’s above the threshold it will fire, even though it was not at or below the threshold first.

Still, that might not be for a while. So, yes, I’d agree you should add the start trigger to that automation, too.

Could be you don’t have the timezone set correctly in both HA and the OS. They both need to be set to the correct timezone (and, of course, agree.) This is a common cause for automations not triggering at the correct time.

EDIT:

Entity_id’s consist of a domain name and an object ID. The domain is the part before the dot, and the object ID is the part after the dot. E.g., for the entity_id light.abc the domain is light and the object_id is abc. As I mentioned before, entity_ids are usually all lower case. Another convention is that domains and object_ids do not contain dots. This goes for automations, too. I would suggest changing your automation aliases to something like:

- alias: Light on when dark

Which will automatically get changed to an object_id of light_on_when_dark (so the automation’s entity_id will be automation.light_on_when_dark.) I doubt this is causing any problems, but probably better to be safe than sorry. :slight_smile:

1 Like

This is really strange. I tried date in the hassio command line and found that it has been set to UTZ (me being CEST). While non of the standard date and time control commands seemed to work and not totally sure, which config file to change (there are several), I got aware that I never bothered to set the timezone in the configuration.yaml. This was also set to UTZ (allthough time in the logs is displayed correctly …). I switched this to my timezone and this seemed to have done the trick (fingers crossed). Thanks once more!

You are right. Thanks.

One more thing, if I may: Using the persistent_notification.create service is somehow anoying, since I have to click to dismiss it and don’t get any timestamps. Is there a nice solution to write these events into their own logfile to have a better overview?

Have you looked at the Logbook?

Thanks for the link. I have to dig deeper into the documentation obviously …
So if I would like to have logs only of my automations, I would probably do something like this:

logbook:
  include:
    domains:
      - automation

Correct? However, I don’t want to lose all the other log entries, that’s why I was asking for a seperate log. Is that possible?

I’ve never used it, but you might try File Notifications.

I us exactly that for my automations, but have to admit, since there’s a lot going on, it does cost processor capacity…

notify:

- name: filed_automations
  platform: file
  filename: filed_automations.txt
 #timestamp: False

automation:

- alias: Automation ran
  id: 'Automation ran'
#  hide_entity: True
  initial_state: 'off'
  trigger:
    platform: event
    event_type: state_changed
  condition:
    condition: template
    value_template: >
      {% set skip_list = ['automation_ran', 'count_warnings', 'count_errors',
                           'activate_map_sensors_actueel', 'call_family_home',
                           'timed_python_scripts_per_20_secs'] %}
      {{ trigger.event.data.entity_id.startswith('automation.') and
         trigger.event.data.entity_id.split('.')[1] not in skip_list and
         'old_state' in trigger.event.data and 'new_state' in trigger.event.data }}
  action:
    - condition: template
      value_template: >
        {{ trigger.event.data.new_state.attributes.last_triggered !=
           trigger.event.data.old_state.attributes.last_triggered }}
    - service: notify.filed_automations
      data_template:
        message: >
         {{ as_timestamp(trigger.event.data.new_state.last_updated)|timestamp_custom("%d %b: %X") }}: {{ trigger.event.data.new_state.name }}
    - service: python_script.last_automation
      data_template:
        event: '{{ trigger.event }}'

python:

# Get params
event = data.get('event')
#logger.error("LAST AUTOMATION: " + str(event))
# Sample: <Event call_service[L]: domain=automation, service=trigger, service_data=entity_id=automation.call_service_event_automation, service_call_id=1972124944-486>

# Find the automation name
#** pos_start = event.find('entity_id=')+10
pos_start = event.find('entity_id=')+21
pos_end = event.find(',', pos_start)

# Get the entity_id
#** entity_id = event[pos_start:pos_end]
entity_id = 'automation.' + event[pos_start:pos_end]

# get the state object
state = hass.states.get(entity_id)

# Make a time string in 24 hour format
#time_string = datetime.datetime.now().strftime('%I:%M')
dt = datetime.datetime.now() #state.attributes.get('last_triggered') #
time = "%02d:%02d:%02d" % (dt.hour, dt.minute, dt.second)
# try to get the automation friendly name
msg = []

try:
    msg = state.name
except:
    msg = None

if msg:
   if not msg.startswith('Set '):
       # Sensor update
       hass.states.set('sensor.last_automation', msg, {
#            'custom_ui_state_card': 'state-card-value_only',
#            'text': sensor_message,
            'unit_of_measurement': 'Aut',
            'friendly_name': time,
            'entity_picture': '/local/buttons/play-mode-repeat.png' })

sensor:

  - platform: file
    file_path: /config/filed_automations.txt
    name: Filed automations

this show the sensor (made by the python script) in the frontend at the top line of the card :

21
(ive have the automation on the bottomline to be able to easily switch on./off for testing purposes

and creates a file filed_automations lf this format:

10 Sep: 17:57:01: Boiler switch
10 Sep: 17:57:51: Update Last Motion
10 Sep: 17:58:23: Update Last Motion
10 Sep: 17:58:28: Update Last Motion
10 Sep: 17:58:50: Update Last Motion
10 Sep: 17:59:03: Call Service Event (Script)
10 Sep: 17:59:05: Forward notifications to filed_notifications
10 Sep: 17:59:05: Call Service Event (Script)
10 Sep: 17:59:05: Call Service Event (Script)
10 Sep: 17:59:05: Announce activity selection
10 Sep: 17:59:06: Notify activity selection
10 Sep: 17:59:13: Activity selection
10 Sep: 18:00:00: Average indoor temp

you can of course take out the python, and the last action to the automation to save some processor power :wink:

1 Like

Can you share your configuration?