HELP bathroom automation

I have been trying to port this piston from smarthings to home assistant but im not smart enough, I will appreciate any help. my goal is
*turn on light when someone enters
*turn off the lights when vacant
*turn fan and lights off after 20 min if no motion and door is close
*turn fan and lights off after 1 min if no motion and door is open
*turn fan on if lights stays on for 3 min and door is closed
I know is a really complex automation but I have all the logic on the previous piston if someone can guide I think this automation can be great for whoever need it

thanks @123Taras for your help so far.

What are you using to determine occupancy (i.e. vacant or not)?

The moment a motion detector turns off is not a reliable indicator of occupancy. The person inside the bathroom may simply be motionless for a brief period of time.

A typical way to determine occupancy is to check for an extended period of “no motion”. For example, when the motion detector changes from on to off and remains off for at least 1 or 2 minutes. That’s a better technique (although not foolproof because they may be sitting on the toilet or in the shower behind a curtain or door) than simply using the moment when the motion detector turns off.

im using a combination of logic in order to determine vacant or nor i.e. if the lights are on but the door is closed and the motion sensor has been inactive for 15 min it means the bathroom is vacant so it will turn off the lights

Your desired automation needs a trigger that detects when the bathroom is unoccupied. You said you are determining occupancy based on the states of various entities. Are you doing this with a Template Binary Sensor?

In other words, how are you planning to implement your second requirement: “turn off the lights when vacant

I can see from the piston’s code that it is using a time period of inactivity (and door and light status).

1 Like

yes I was looking to add an integer of time for that reason. like if certain amount of time since last motion plus door close or open then turn off, but here is when I said im not that smart lol.

Your piston sets warnDelay to 900 seconds = 15 minutes. That means it waits for the motion detector to turn off and stay off for at least 15 minutes as the basis for declaring no occupancy. Is that correct (because it seems quite long)?

yes that’s correct, but is because warndelay can have 2 values depending the other conditions

I’m not fluent in creating pistons but it seems to me that there are things happening in it (like dynamically setting a variable value based on certain conditions) that haven’t been mentioned in your first post’s five (fairly straightforward) requirements.

I started creating an automation based on the five original requirements but I now see it won’t meet the additional requirements within the piston’s code. That’s my fault; I should have examined the piston carefully. The changes needed to adapt my example exceed my currently available time and interest. I am politely bowing out and hope someone else will come to your assistance. Good luck.

thank for your help its a lot appreciated. if I come up with something ill post it here. or maybe ill look different approaches if you still want to share what you have in mind I will be grateful to try it thanks for your time

This will merely serve as a possible framework for what you actually want but, in its current form, doesn’t behave exactly like your piston.

alias: example 1
id: example_1
mode: single
max_exceeded: silent

trigger:
- id: 'occupancy'
  platform: state
  entity_id: binary_sensor.bathroom_motion
  from: 'off'
  to: 'on'

- id: 'no_occupancy_1'
  platform: state
  entity_id: binary_sensor.bathroom_motion
  from: 'on'
  to: 'off'
  for: '00:01:00'

- id: 'no_occupancy_20'
  platform: state
  entity_id: binary_sensor.bathroom_motion
  from: 'on'
  to: 'off'
  for: '00:20:00'

- id: 'lights_on_3'
  platform: state
  entity_id: light.bathroom_light
  from: 'off'
  to: 'on'
  for: '00:03:00'

condition: []

action:
- variables:
    light: 'light.bathroom_light'
    fan: 'switch.bathroom_fan'
    door: 'binary_sensor.bathroom_door'

- choose:
  - conditions:
    - "{{ trigger.id == 'occupancy'}}"
    - "{{ is_state(light, 'off') }}"
    sequence:
    - service: light.turn_on
      target:
        entity_id: '{{ light }}'

  - conditions:
    - "{{ trigger.id == 'no_occupancy_1'}}"
    - "{{ is_state(light, 'on') }}"
    sequence:
    - service: light.turn_off
      target:
        entity_id: '{{ light }}' 

  - conditions:
    - "{{ trigger.id == 'no_occupancy_20'}}"
    - "{{ is_state(door, 'off') }}"
    sequence:
    - service: homeassistant.turn_off
      target:
        entity_id:
        - '{{ light }}'
        - '{{ fan }}'

  - conditions:
    - "{{ trigger.id == 'lights_on_3'}}"
    - "{{ is_state(door, 'off') }}"
    sequence:
    - service: switch.turn_on
      target:
        entity_id: '{{ fan }}' 

  default: []

definitely better than my big “nothing” you are one of the best in this forum

I have been. workin in base to your suggestion but I got errors can you check what im doing wrong @123Taras

alias: bathroom experiment 1
id: example_1
mode: single
max_exceeded: silent

trigger:

  • id: ‘occupancy’
    platform: state
    entity_id: group.bathroom_motion
    from: ‘off’
    to: ‘on’

  • id: ‘door_open’
    platform: state
    entity_id: group.bathroom_door
    from: ‘off’
    to: ‘on’

  • id: ‘no_occupancy_3’
    platform: state
    entity_id: group.bathroom_motion
    from: ‘on’
    to: ‘off’
    for: ‘00:03:00’

  • id: ‘no_occupancy_10’
    platform: state
    entity_id: group.bathroom_motion
    from: ‘on’
    to: ‘off’
    for: ‘00:10:00’

  • id: ‘lights_on_3’
    platform: state
    entity_id: light.bath_light on_off
    from: ‘off’
    to: ‘on’
    for: ‘00:03:00’

  • id: ‘showerOn’
    platform: state
    entity_id: binary_sensor.bathroom_hygrostat
    from: ‘off’
    to: ‘on’
    for: ‘00:01:00’

  • id: ‘showerOff’
    platform: state
    entity_id: binary_sensor.bathroom_hygrostat
    from: ‘on’
    to: ‘off’
    for: ‘00:05:00’

condition: []

action:

  • variables:
    light: ‘light.bath_light on_off’
    fan: ‘switch.tz3000_ji4araar_ts0011_4c755449_on_off’
    door: ‘group.bathroom_door’

  • choose:

    • conditions:

      • “{{ trigger.id == ‘occupancy’}}”
      • “{{ is_state(light, ‘off’) }}”
        sequence:
      • service: light.turn_on
        target:
        entity_id: ‘{{ light }}’
    • conditions:

      • “{{ trigger.id == ‘door_open’}}”
      • “{{ is_state(light, ‘off’) }}”
        sequence:
      • service: light.turn_on
        target:
        entity_id: ‘{{ light }}’
    • conditions:

      • “{{ trigger.id == ‘no_occupancy_3’}}”
      • “{{ is_state(light, ‘on’) }}”
      • “{{ is_state(door, ‘on’) }}”
        sequence:
      • service: light.turn_off
        target:
        entity_id: ‘{{ light }}’
    • conditions:

      • “{{ trigger.id == ‘no_occupancy_10’}}”
      • “{{ is_state(door, ‘off’) }}”
        sequence:
      • service: homeassistant.turn_off
        target:
        entity_id:
        • ‘{{ light }}’
        • ‘{{ fan }}’
    • conditions:

      • “{{ trigger.id == ‘‘showerOn’’}}”
      • “{{ is_state(door, ‘off’) }}”
        sequence:
      • service: switch.turn_on
        target:
        entity_id: ‘{{ fan }}’
    • conditions:

      • “{{ trigger.id == ‘‘showerOff’’}}”
        sequence:
      • service: switch.turn_off
        target:
        entity_id: ‘{{ fan }}’

this is the error Message malformed: invalid template (TemplateSyntaxError: expected token ‘end of print statement’, got ‘showerOn’) for dictionary value @ data[‘action’][1][‘choose’][4][‘conditions’][0][‘value_template’

check the quotation marks here in these two templates:

conditions:

“{{ trigger.id == ‘‘showerOn’’}}”
“{{ is_state(door, ‘off’) }}”
sequence:
service: switch.turn_on
target:
entity_id: ‘{{ fan }}’
conditions:

“{{ trigger.id == ‘‘showerOff’’}}”
sequence:
service: switch.turn_off
target:
entity_id: ‘{{ fan }}’

should be:

conditions:

"{{ trigger.id == 'showerOn'}}"
"{{ is_state(door, ‘off’) }}"
sequence:
service: switch.turn_on
target:
entity_id: '{{ fan }}'
conditions:

"{{ trigger.id == 'showerOff'}}"
sequence:
service: switch.turn_off
target:
entity_id: '{{ fan }}'

also you should edit your post to correctly show the code formatting (``` both before and after the code).

alias: bathroom experiment
description: ''
trigger:
  - platform: state
    entity_id: group.bathroom_motion
    id: occupancy
    from: 'off'
    to: 'on'
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - platform: state
    entity_id: group.bathroom_motion
    id: no_occupancy_3
    from: 'on'
    to: 'off'
    for:
      hours: 0
      minutes: 3
      seconds: 0
  - platform: state
    entity_id: group.bathroom_motion
    id: no_occupancy_10
    from: 'on'
    to: 'off'
    for:
      hours: 0
      minutes: 10
      seconds: 0
  - platform: state
    entity_id: group.bathroom_door
    id: door_open
    from: 'off'
    to: 'on'
  - platform: state
    entity_id: binary_sensor.bathroom_hygrostat
    id: shower_on
    from: 'off'
    to: 'on'
    for:
      hours: 0
      minutes: 1
      seconds: 0
  - platform: state
    entity_id: binary_sensor.bathroom_hygrostat
    id: shower_off
    from: 'on'
    to: 'off'
    for:
      hours: 0
      minutes: 5
      seconds: 0
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: occupancy
          - condition: device
            type: is_off
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
        sequence:
          - type: turn_on
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id: door_open
          - condition: device
            type: is_off
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
        sequence:
          - type: turn_on
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id: no_occupancy_3
          - condition: device
            type: is_on
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
          - condition: state
            entity_id: group.bathroom_door
            state: 'on'
        sequence:
          - type: turn_off
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id: no_occupancy_10
          - condition: device
            type: is_on
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
          - condition: state
            entity_id: group.bathroom_door
            state: 'off'
        sequence:
          - type: turn_off
            device_id: 994c822d18ff7259d7ed441c8731a423
            entity_id: light.bath_light_on_off
            domain: light
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id: shower_on
          - condition: state
            entity_id: group.bathroom_door
            state: 'off'
        sequence:
          - type: turn_on
            device_id: 7577c411d5214086832ca0f51eee94e2
            entity_id: switch.tz3000_ji4araar_ts0011_4c755449_on_off
            domain: switch
    default: []
  - choose:
      - conditions:
          - condition: trigger
            id: shower_off
          - condition: device
            type: is_on
            device_id: 7577c411d5214086832ca0f51eee94e2
            entity_id: switch.tz3000_ji4araar_ts0011_4c755449_on_off
            domain: switch
        sequence:
          - type: turn_off
            device_id: 7577c411d5214086832ca0f51eee94e2
            entity_id: switch.tz3000_ji4araar_ts0011_4c755449_on_off
            domain: switch
    default: []
mode: single


I think I fix it. now I just have to tailored it more. this is what I came up so far

Tip

Avoid using Device Actions (and Device Conditions and Device Triggers). They don’t support templates and they’re easily twice as verbose as State Conditions, Template Conditions, Service calls, etc.

Compare how long-winded your automation has become compared to the original example (without any significant additional functionality).

I will look into this but so far is working :sweat_smile::sweat_smile: