Automation with DeepStack And Motions Sensors

Hi,

Finally I got everything up and running using Deepstack and my Unifi Cameras and I’m now trying to set up an Automation, that captures my camera feed when motion is detected on one of my Xiaomi PIR Sensors.

So I created two automations, that triggers every 25 second for persons and every 30 second for cars, when my condition is met (which is an input boolean), that goes from ‘off’ to ‘on’ when my Motion Detecter is triggered. When the motion stops and the Sensor goes from ‘on’ to ‘off’, the automations stops.

What I’m not happy about is, when the motion is triggered, then I assume that the “timer” will start and then first do my automation after 25 seconds and 30 seconds - or am I wrong?
Obviously I want the automation to get fired when the motion is triggered and then afterwards every 25 and 30 second while the condition is met. How can I accomplish that?

My Automation for both Persons and Cars:

### Front - Camera Motion Notification Person ###
- alias: 'Front Camera Motion Notification Person'
  trigger:
    platform: time_pattern
    seconds: "/25"
  condition:
    - condition: state
      entity_id: input_boolean.deepstack_motion_keepalive
      state: 'on'
  action:
    - service: image_processing.scan
      entity_id: image_processing.front_object
    - service: image_processing.scan
      entity_id: image_processing.front_face
    - delay: 2
    - service_template: '{% if (states.image_processing.front_object.state | int) > 0 %} notify.android {% endif %}'
      data_template:
        message: >
          {% if (states.image_processing.front_face.attributes.total_matched_faces | int) > 0 %}
            Hey, {{ states.image_processing.front_face.attributes.matched_faces }} ! {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% else %}
            Who is that!? {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% endif %}
        data:
          image: 'https://lalala:8123/local/deepstack_person_images/front/deepstack_latest_person.jpg'
          
### Front - Camera Motion Notification Car ###
- alias: 'Front Camera Motion Notification Car'
  trigger:
    platform: time_pattern
    seconds: "/30"
  condition:
    - condition: state
      entity_id: input_boolean.deepstack_motion_keepalive
      state: 'on'
  action:
    - service: image_processing.scan
      entity_id: image_processing.front_object_car
    - delay: 2
    - service_template: '{% if (states.image_processing.front_object_car.state | int) > 0 %} notify.android {% endif %}'
      data_template:
        message: 'Car spottet {{now().strftime("%H:%M:%S %d-%m-%Y")}}'
        data:
          image: 'https://lalala:8123/local/deepstack_car_images/front/deepstack_latest_car.jpg'

Is my approach completely off here or could I do the whole thing smarter?

Thanks…

In general I’d say this is a simple way to do almost what you want. I say almost because it doesn’t trigger immediately when the input_boolean changes to on, but can take up to 25/30 seconds.

Another way that comes to mind is to trigger the automation with the input_boolean changing to on, then in the action start a timer. Then have the timer finishing be another trigger. And leave in the condition part, too. This way it will trigger immediately when the input_boolean first goes on. Then when the timer finishes (25/30 seconds later), if the input_boolean is still on, then the automation will trigger again. This will repeat until the input_boolean goes off.

BTW, you shouldn’t have a service_template where the template may evaluate to nothing. When that happens you’ll get an error and the automation will abort.

Can you point out where that is, because currently I don’t see any errors and everything seems to fire correctly?

service_template: '{% if (states.image_processing.front_object.state | int) > 0 %} notify.android {% endif %}'

and

service_template: '{% if (states.image_processing.front_object_car.state | int) > 0 %} notify.android {% endif %}'

Neither of these have an {% else %} ...

I’m really not that sharp at this yet, so should I then leave it as: service: ?

Either the template you use with service_template has to always evaluate to a valid service name, or you need to figure out another way to achieve what you want.

In this particular case, it’s probably better to use a condition step. E.g.:

    - condition: numeric_state
      entity_id: image_processing.front_object
      above: 0
    - service: notify.android
      data_template:
        message: >
          {% if (states.image_processing.front_face.attributes.total_matched_faces | int) > 0 %}
            Hey, {{ states.image_processing.front_face.attributes.matched_faces }} ! {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% else %}
            Who is that!? {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% endif %}
        data:
          image: 'https://lalala:8123/local/deepstack_person_images/front/deepstack_latest_person.jpg'

Oh okay. It just weird that it actually works then. The sensor gets triggered and no persons are there I won’t get notified.
If a person is present and the face is known, then I get the “Hey, Name + Confidence” !
Finally if the person in the picture is not known, then I get the “Who is that!?”

So it seems to working though :thinking:

You’re probably just not looking in the log to see the error. Yes, if image_processing.front_object's state is 0, you won’t see any notification, because it will cause an error and the rest of the steps will be aborted. So I guess it “works”, but only because two wrongs make a right. :wink:

Haha… isnt it lovely with some noobs around :smile:

1 Like

So it would end up looking like this (I use the and in the conditions right, to make sure both conditions are met)!?:

### Front - Camera Motion Notification Person ###
- alias: 'Front Camera Motion Notification Person'
  trigger:
    platform: time_pattern
    seconds: "/25"
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: input_boolean.deepstack_motion_keepalive
        state: 'on'
      - condition: numeric_state
        entity_id: image_processing.front_object
        above: 0
  action:
    - service: image_processing.scan
      entity_id: image_processing.front_object
    - service: image_processing.scan
      entity_id: image_processing.front_face
    - delay: 2
    - service: notify.android
      data_template:
        message: >
          {% if (states.image_processing.front_face.attributes.total_matched_faces | int) > 0 %}
            Hey, {{ states.image_processing.front_face.attributes.matched_faces }} ! {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% else %}
            Who is that!? {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% endif %}
        data:
          image: 'https://lalala:8123/local/deepstack_person_images/front/deepstack_latest_person.jpg'

No. The condition would be used in the action part, right before the service call (which used to use service_template), just as I showed it.

Oh I didn’t know that was possible - I just thought you shrinked to show the “meaning”.
LOL - Are we getting closer:

### Front - Camera Motion Notification Person ###
- alias: 'Front Camera Motion Notification Person'
  trigger:
    platform: time_pattern
    seconds: "/25"
  condition:
    - condition: state
      entity_id: input_boolean.deepstack_motion_keepalive
      state: 'on'
  action:
    - service: image_processing.scan
      entity_id: image_processing.front_object
    - service: image_processing.scan
      entity_id: image_processing.front_face
    - delay: 2
    - condition: numeric_state
      entity_id: image_processing.front_object
      above: 0
    - service: notify.android
      data_template:
        message: >
          {% if (states.image_processing.front_face.attributes.total_matched_faces | int) > 0 %}
            Hey, {{ states.image_processing.front_face.attributes.matched_faces }} ! {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% else %}
            Who is that!? {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% endif %}
        data:
          image: 'https://lalala:8123/local/deepstack_person_images/front/deepstack_latest_person.jpg'

Yes, that’s what I was thinking.

BTW, do you realize that your trigger will not cause the automation to run every 25 seconds? It will run at xx:xx:00, xx:xx:25 and xx:xx:50, and then repeat. So 25, 25, 10, 25, 25, 10, …

No, but I do now :smile:. I really like the thought you got with the timer. I’ve never used timer before…
Could you try to modify the latest Automation and show me what you meant, so that I get the picture as soon as the motion is triggered and then after every 25th second, until the input boolean goes off?

  trigger:
    - platform: state
      entity_id: input_boolean.deepstack_motion_keepalive
      to: 'on'
    - platform: event
      event_type: timer.finished
      event_data:
        entity_id: timer.person
  condition:
    - condition: state
      entity_id: input_boolean.deepstack_motion_keepalive
      state: 'on'
  action:
    - service: timer.start
      entity_id: timer.person
   ...

And declare the timer:

timer:
  person:
    duration: '00:00:25'

I think we are close to my longest automation ever :astonished:
Then I end up with something like this:

### Front - Camera Motion Notification Person ###
- alias: 'Front Camera Motion Notification Person'
  trigger:
    - platform: state
      entity_id: input_boolean.deepstack_motion_keepalive
      to: 'on'
    - platform: event
      event_type: timer.finished
      event_data:
        entity_id: timer.person
  condition:
    - condition: state
      entity_id: input_boolean.deepstack_motion_keepalive
      state: 'on'
  action:
    - service: timer.start
      entity_id: timer.person
    - service: image_processing.scan
      entity_id: image_processing.front_object
    - service: image_processing.scan
      entity_id: image_processing.front_face
    - delay: 2
    - condition: numeric_state
      entity_id: image_processing.front_object
      above: 0
    - service: notify.android
      data_template:
        message: >
          {% if (states.image_processing.front_face.attributes.total_matched_faces | int) > 0 %}
            Hey, {{ states.image_processing.front_face.attributes.matched_faces }} ! {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% else %}
            Who is that!? {{now().strftime("%H:%M:%S %d-%m-%Y")}}
          {% endif %}
        data:
          image: 'https://lalala:8123/local/deepstack_person_images/front/deepstack_latest_person.jpg'

What do you think :blush:?

1 Like

Looks good to me.

I’ll test tomorrow and let you know!
Thanks for your kindness and patience :slight_smile:

1 Like

Yes sir! I added the rule, went out this morning and it got fired. The timer started brilliantly and I could see the Object_face ran approx. every 25 second.

The only thing that didn’t seem to happen, is the notification I expect to get right after the sensor is triggered. So I had to wait the 25 seconds before the event got fired?

Maybe the 2 second delay is not long enough??? It will only get to the notify.android step if, after the 2 second delay, the state of image_processing.front_object is a numeric value above zero. Or maybe it should be testing the value of image_processing.front_face instead???