The change from 1.2.3 to 1.2.5 in the amcrest package really only had to do with error handling. If the maximum number of retries was exceeded on a command transfer, the old version would not raise an exception but, e.g., the returned snapshot would just be empty.
The improvements in the snapshot handling were done in the HA amcrest component. If you’re using my latest custom component (just checked in), then you should have those changes. Or, if you’re using the standard component, you can get the updates from HA’s dev branch. These make sure that multiple threads attempting to get a snapshot from the camera don’t step on each other’s toes, resulting in errors that can slow things down. There can be (at least) three threads – the “thumbnail” picture on the frontend, the full picture in the “window” that appears “above” the thumbnail when you click on it, and a call to the camera.snapshot service, say in an automation.
I used to use motion detection in the cameras, and I had them set up to send an e-mail to me when motion was detected, strictly outside of HA. Inside HA I did use the binary_sensor to do other things when the cameras detected motion.
But now I use PIR sensors for motion detection, because it was just too difficult to get the camera motion detection to work well in all situations. So to get the snapshots now I came up with a combination of things, resulting in local_file cameras displaying the latest snapshot from each camera.
Here is part of the implementation from a package file:
camera:
- platform: local_file
name: LR IPC Last Motion
file_path: /home/homeassistant/.homeassistant/snapshots/lr_ipc_motion_last.jpg
- platform: local_file
name: HF IPC Last Motion
file_path: /home/homeassistant/.homeassistant/snapshots/hf_ipc_motion_last.jpg
shell_command:
update_snaps: python3 /home/homeassistant/.homeassistant/update_snaps.py
automation:
- alias: Foyer Snapshot
trigger:
- platform: numeric_state
entity_id: sensor.foyer_burglar
above: 0
condition:
- condition: template
value_template: >
{{ states('camera.lr_ipc') in ('streaming', 'recording') }}
action:
- wait_template: "{{ is_state('script.snap', 'off') }}"
- service: script.snap
data:
camera: lr
- alias: House Front Snapshot
trigger:
- platform: state
entity_id: binary_sensor.hf_motion
to: 'on'
action:
- wait_template: "{{ is_state('script.snap', 'off') }}"
- service: script.snap
data:
camera: hf
script:
snap:
sequence:
- service: camera.snapshot
data_template:
entity_id: camera.{{ camera }}_ipc
filename: >
/home/homeassistant/.homeassistant/snapshots/{{
camera
}}_ipc_motion_{{
utcnow().strftime('%Y%m%d_%H%M%S')
}}.jpg
- service: shell_command.update_snaps
And here’s update_snaps.py:
#!/usr/bin/env python3
from glob import glob
import os
MAX_SNAPS = 25
SNAPS_DIR = '/home/homeassistant/.homeassistant/snapshots'
SNAPS = [('lr_ipc_motion_[0-9]*.jpg', 'lr_ipc_motion_last.jpg'),
('hf_ipc_motion_[0-9]*.jpg', 'hf_ipc_motion_last.jpg')]
for snap in SNAPS:
snap_list = sorted(glob(os.path.join(SNAPS_DIR, snap[0])))
snap_link = os.path.join(SNAPS_DIR, snap[1])
try:
os.remove(snap_link)
except:
pass
if snap_list:
os.symlink(snap_list[-1], snap_link)
for f in snap_list[:-MAX_SNAPS]:
os.remove(f)
else:
os.symlink('no_image.jpg', snap_link)
I’m in the process of updating this script so I can scroll through the available snapshots for each camera with buttons in the frontend, but that’s not ready for prime time yet.
EDIT: I changed the file name timestamp from local time to UTC. It wasn’t an issue when going to DST, but it would have been later this year when coming from DST!