Order of Actions in Automation: Light-On / Picture / Light-Off

Dear community

I am reading the analog thermometer of our hot-water boiler using an ESP-Cam and ppf.angauge. The picture-to-temperature conversion works well, but I am struggling with more basic things: The thermometer is in a dark place. Therefore, I use the built-in LED of the ESP-Cam to illuminate the scene.

To take proper pictures, I need the illumination to turn on, first. Then the camera is supposed to take a picture. And afterwards the illumination turns off.

However, I need to use a ridiculously long delay (5 seconds) between light-on and shot to reliably avoid getting dark frames. To use ppf.angauge, I write a custom_component in python. However, the same problem happens with a normal automation (see below).

I assumed that HA executes the actions in the order I give them. I understand that HA works asynchronously: It may do something else while waiting for the ESP-Cam to turn on the LED. But nevertheless I would expect it to execute the next action in my sequence only after completing the first one.

Am I wrong?

Or does the ESP-Cam not actually trigger an exposure when I tell it to, but merely sends the last frame it had already taken earlier (maybe even before I turned on the light)?

Any help or tipps on how to diagnose the problem further are appreciated.

actions:
  - type: turn_on
    device_id: ...
    entity_id: ...
    domain: light
    brightness_pct: 100
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - action: camera.snapshot
    metadata: {}
    data:
      filename: >-
        /media/boiler/{{ utcnow() | as_timestamp |
        timestamp_local('0000-12-31T00:00:00') }}.jpg
    target:
      device_id: ...
      entity_id: camera.boiler_kamera
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 100
  - type: turn_off
    device_id: ...
    entity_id: ...
    domain: light

Can’t answer your question, but I have 1 of my own.

Are you sure the dark frames are due to the initial delay & not the subsequent one?
Asking because 100ms delay might start turning off the light before the camera is done taking the picture.

For reliability and performance you can also consider creating a script directly in ESPHome — to run directly on the ESP, but triggered from HA.

Hi ShadowFist

I’m sure, yes. I started from extremely large delays (on both ends) and reduced them until I got dark frames. The values I posted are the minimum values I can get away with without getting dark frames.

You are referring to just the part related to LED-on / capture / LED-off, I guess? That sounds very promising (although I would still like to know what is going on with my automation). Is that possible on ESPHome-yaml grounds or would I have to use C++?

Yes

The actions you have invoked remotely from HA is natively available in ESPHome too – so you can do this in YAML.

:+1: Going to try.

I still think this is a promising approach, but I’m struggling a bit. I have no problem toggling the LED and doing delays in a script. Also, I can link this to a button that I can press from Home-Assistant. But how am I supposed to capture an image and send it to HA?

esp32_camera:
  name: Kamera
  ... <shortened>

light:
  - platform: binary
    output: boilerLED
    id: illumination

script:
  - id: capture
    then:
      - light.turn_on: illumination
      - delay: 1s
      - light.turn_off: illumination
    mode: queued

button:
  - platform: template
    name: "capture image"
    on_press:
      then:
        - script.execute: capture

Hmm, you got me there. After some research, it doesn’t look like my idea is as simple as I first thought. ESPHome doesn’t have the equivalent of HA’s file camera component to expose a stored image as a new camera, but I found something else. I cannot test this, unfortunately.

The ESP camera has an on_image automation, so you could do something like this which should then run automatically when you take a snapshot:

esp32_camera:
  ...
  on_image:
    then:
      - light.turn_on: illumination
      - delay: 1s
      - light.turn_off: illumination

That wont work: on_image is called after the image has been taken: The docs say that the image is available in a variable:

1 Like

Bugger, you’re right… Back to HA then, I guess.

Going back to your original issue, there is something else you could try, at least for debugging. It’s ugly for me, so I wouldn’t stick with this, but hopefully it can give you some info.

You can still have a script within ESPHome, but make a call back to HA to perform the actual snapshot. Seems there’s no way to get a stored image otherwise, except to push it via HTTP to a custom web server.

Something like this:

script:
  - id: snapshot_with_light
    then:
      - light.turn_on: illumination
      - delay: 1000ms
      - homeassistant.service:
          service: camera.snapshot
          data:
            entity_id: camera.my_cam
            filename: >-
              /media/boiler/{{ utcnow() | as_timestamp |
        timestamp_local('0000-12-31T00:00:00') }}.jpg
      - light.turn_off: illumination

The other thing we don’t know here is how long it takes for that camera’s exposure to stabilise after a lighting change.