The most difficult part of this is when there are no lights to turn off. In that case you can’t really call the light.turn_off service with an empty list of light entity_id’s. So you’d have to add a condition step first, which would end up doing most of the same work as the step that actually generates the list of entity_id’s to turn off.
The easiest way to do this is actually via a python_script instead of a “regular” YAML script. E.g.:
entities = []
if hass.states.get('binary_sensor.motion_sensor_158d0001d5403a').state == 'off':
entities.append('light.hallway')
if hass.states.get('binary_sensor.motion_sensor_158d0001d694b2').state == 'off':
entities.append('light.landing')
if (hass.states.get('binary_sensor.motion_sensor_158d0001a90d90').state == 'off' and
hass.states.get('binary_sensor.motion_sensor_158d0001b1956a').state == 'off'):
entities.append('light.kitchen')
# Add more like above for additional sensors & lights here...
if entities:
hass.services.call('light', 'turn_off', {'entity_id': entities})
EDIT: Corrected mistake @Knottyboy discovered; i.e., append .state to each get() call.
This is what I have (also double checked binary sensors and light names):
entities = []
if hass.states.get('binary_sensor.motion_sensor_158d0001d5403a') == 'off':
entities.append('light.hallway')
if hass.states.get('binary_sensor.motion_sensor_158d0001d694b2') == 'off':
entities.append('light.landing')
if (hass.states.get('binary_sensor.motion_sensor_158d0001a90d90') == 'off' and
hass.states.get('binary_sensor.motion_sensor_158d0001b1956a') == 'off'):
entities.append('light.kitchen')
if hass.states.get('binary_sensor.motion_sensor_158d0001e7a5a7') == 'off':
entities.append('light.bedroom_light')
if hass.states.get('binary_sensor.motion_sensor_158d0001b19555') == 'off':
entities.append('light.childone_light')
if hass.states.get('binary_sensor.motion_sensor_158d0001e19504') == 'off':
entities.append('light.childtwo_light')
if hass.states.get('binary_sensor.motion_sensor_158d0001d90b5d') == 'off':
entities.append('light.porch_light')
if hass.states.get('binary_sensor.motion_sensor_158d0001e5eae8') == 'off':
entities.append('light.livingroom')
if entities:
hass.services.call('light', 'turn_off', {'entity_id': entities})
Edit:
I’ve also tried reducing it to just the one light and it still doesn’t work:
entities = []
if hass.states.get('binary_sensor.motion_sensor_158d0001e5eae8') == 'off':
entities.append('light.livingroom')
if entities:
hass.services.call('light', 'turn_off', {'entity_id': entities})
Edit 2:
I have the day off work and was determined to get this done. It’s missing .state at the end of hass.states.get(). It was pulling through all the values associated with the motion sensor (last motion, on/off ect).
Thanks for this man, but I have something similar implemented. This is to run off the back of a button press. My wife likes to leave lights on in rooms she’s not in (to be fair after some moaning she has cut down). I have a button on the side of our bed and it would be nice to turn off all lights where there is no motion (if the kids are up I don’t want to turn their lights off).
Also when I do use the timer to turn them off it’s difficult for rooms like the living room (sitting still on the sofa).
You may have noticed earlier in the thread I had two sensors for kitchen, I’ll be creating a template binary sensory to replace motion_sensor_158d0001a90d90 with.
Glad to help, and sorry for the mistake in my original suggestion. (I’m going to go back and edit it so people who come across this topic later don’t get misled by it if they don’t read the rest of the posts.)
FWIW, the way you have it now is a bit inefficient. It’s calling the service for every light that needs to be turned off. It’s much more efficient to do that with a list of light entities, like in my original suggestion – which would have worked if .state had been appended to each of the get() calls (as you discovered.) Actually you can still do that with your implementation, by changing the last part to:
entity_ids = []
for lightv, onoffv in entities:
if onoffv == 'off':
entity_ids.append(lightv)
hass.services.call('light', 'turn_off', {'entity_id': entity_ids})
you then could filter out the last part of the binary into a variable
{% set s = ‘binary_sensor.motion_sensor_livingroom’.split(’.’)[-1].split(’_’)[-1] %}
and use that in the service_template and entity_id template?
Or wouldn’t that help is this case.