For me the only way to make it work is restarting HA.
Wow, just love this integration! @briis, not only are you one of the best cyclists in the world you have also done an amazing job on this Thanks a lot for all your work, this component truly makes a difference for me!
Can I just ask if anyone has any feedback to give on the following:
-
Image that is saved getās strange proportions, looks like it is streched out. I have configured my G4 with the code below and use it in an automation to send a snapshot. I only use the smart detection of the camera.
-
Sometimes it misses to save the image. Example: I went out for a walk, when I left I got a notification but not when I returned, but I was captured in UniFi Protect so the camera triggered. Hard to debug, I know, just wanted to ehar if anyone else has experienced the same.
-
Has anyone found a good solution in an automation to have a dynamic file name? As it is now with my code the image is overwritten everytime there is a new motion. I would like to write the file with a unique filename adn then, when sending the notification, use the same file name. Probably not too hard to do but havenāt succeeded so far
-
Finally, what mode in the automations do you use for queuing the automation jobs for sending notification with an image (single, restart, queued, parallel)?
My code:
- id: '1612642603691'
alias: KAMERA - G4 Garageuppfarten
description: Notis med bild
trigger:
- entity_id: binary_sensor.motion_g4_garageuppfart
platform: state
to: 'on'
condition: []
action:
- delay: '10'
- service: unifiprotect.save_thumbnail_image
data:
entity_id: camera.g4_garageuppfarten
filename: /config/www/camera_g4_garageuppfarten.png
image_width: 2688
- service: notify.mobile_app_pixel_5
data:
message: Rƶrelse pƄ garageuppfarten
data:
image: https://xxx.duckdns.org/local/camera_g4_garageuppfarten.png
mode: single
Thanks, and I do actually cycle
Let me try and answer your questions:
The snapshot feature has a fixed size, so I recommend you use the camera.snapshot
service instead, that will also solve your question 2, as thumbnails are only generated once the motion has completed, so there is a delay and that is why you see the inconsistencies.
You could create a Script that does this, and then in the beginning of the script define a variable with a date_time syntaks, like this: "video_{{ (as_timestamp(now()) | timmestamp_custom('%Y_%m_%d_%H_%M_%S', true)) }}"
And then use that variable later in your script. See more here Scripts - Home Assistant
The thumbnail is created by the controller once the event has finished - your automation triggers when motion starts, so longer motion events will outlast your 10 second delay and the thumbnail will not be available.
Still yet to refine my current G4 automation to send smart object detection events when first triggered, but the current state (including dynamic file name for the notification) is below in case it helps.
Notes:
- I use the event score and length to provide additional filtering of motion events unless the motion is a smart detection of an object.
- I trigger on the end of the motion event to ensure that the thumbnail is available (only seems to 404 when itās raining). Iām planning to move the person / vehicle smart detections to be triggered on the start of a motion event and captured with a snapshot, but havenāt got round to it yet.
- On HA startup I load sensors with local and remote image paths from my secrets.yaml for easy maintenance.
- I use the original driveway_motion.jpg to provide a picture entity in my dashboard for the last motion event, and send the copied image with a dynamic file name as the notification. Images are cleaned up with a maintenance automation that runs a command line removal of images over 14 days old.
- The camera always records but whether we are notified or not depends on input_boolean.notify_driveway which is set by time of day or through the dashboard.
- /lovelace/camera_driveway is a hidden Lovelace view / tab with a panel mode live view picture entity showing the driveway camera.
- Notification is sent to the official Android companion app.
- id: unifiprotect_driveway_motion_notification
alias: "Driveway Motion Notification"
mode: queued
trigger:
platform: state
entity_id: binary_sensor.motion_driveway
from: "on"
to: "off"
condition:
condition: and
conditions:
- condition: template
value_template: >
{{ ((is_state('sun.sun', 'above_horizon') and (state_attr('binary_sensor.motion_driveway', 'event_score') | int >= 50)))
or ((is_state('sun.sun', 'below_horizon') and (state_attr('binary_sensor.motion_driveway', 'event_score') | int >= 50)))
or (not is_state_attr('binary_sensor.motion_driveway', 'event_object', 'None Identified')) }}
- condition: template
value_template: >
{{ (is_state('sun.sun', 'above_horizon') and (state_attr('binary_sensor.motion_driveway', 'event_length') | int >= 6))
or (is_state('sun.sun', 'below_horizon') and (state_attr('binary_sensor.motion_driveway', 'event_length') | int >= 12))
or (not is_state_attr('binary_sensor.motion_driveway', 'event_object', 'None Identified')) }}
action:
- variables:
notify_image: "driveway_motion_{{ now().strftime('%Y%m%d%H%M') }}.jpg"
motion_type: "{{ 'Motion' if is_state_attr('binary_sensor.motion_driveway', 'event_object', 'None Identified') else (state_attr('binary_sensor.motion_driveway', 'event_object') | capitalize) }}"
motion_score: "{{ state_attr('binary_sensor.motion_driveway', 'event_score') }}"
motion_length: >
{% set time = (state_attr('binary_sensor.motion_driveway', 'event_length') | int) %}
{% set mins = ((time % 3600) / 60) | int %}
{% set secs = time - (mins * 60) %}
{% if time < 60 %}{{ secs }} seconds
{% else %}{{ mins }} minutes {{ secs }} seconds
{% endif %}
- service: input_datetime.set_datetime
data:
entity_id: input_datetime.last_driveway_motion
time: "{{ (as_timestamp(now()) | timestamp_custom('%H:%M:%S', true)) }}"
date: "{{ (as_timestamp(now()) | timestamp_custom('%Y-%m-%d', true)) }}"
- choose:
- conditions:
# no object type detected, just motion
- condition: template
value_template: "{{ not is_state('sensor.motion_recording_driveway', 'never') }}"
- condition: template
value_template: "{{ is_state_attr('binary_sensor.motion_driveway', 'event_object', 'None Identified') }}"
sequence:
- delay: "00:00:05"
- condition: state
entity_id: binary_sensor.motion_driveway
state: "off"
- service: unifiprotect.save_thumbnail_image
data:
entity_id: camera.driveway
filename: "{{ states('sensor.snapshot_local') }}driveway_motion.jpg"
image_width: 2688
- conditions:
# object detected (person, etc) - don't specify image width
- condition: template
value_template: "{{ not is_state('sensor.motion_recording_driveway', 'never') }}"
sequence:
- delay: "00:00:05"
- condition: state
entity_id: binary_sensor.motion_driveway
state: "off"
- service: unifiprotect.save_thumbnail_image
data:
entity_id: camera.driveway
filename: "{{ states('sensor.snapshot_local') }}driveway_motion.jpg"
default:
- service: camera.snapshot
data:
entity_id: camera.driveway
filename: "{{ states('sensor.snapshot_local') }}driveway_motion.jpg"
- service: shell_command.copy_file
data:
src_file: "{{ states('sensor.snapshot_local') }}driveway_motion.jpg"
dst_file: "{{ states('sensor.snapshot_local') }}{{ notify_image }}"
- choose:
- conditions:
- condition: and
conditions:
- condition: state
entity_id: input_boolean.notify_driveway
state: "on"
- condition: state
entity_id:
- input_boolean.holiday_mode
- input_boolean.notify_via_sms
state: "off"
sequence:
- service: notify.all_mobile
data:
title: "Driveway Alert"
message: >
{{ motion_type }} at {{ as_timestamp(state_attr('binary_sensor.motion_driveway', 'last_tripped_time')) | timestamp_custom('%H:%M') }}.<br>
Score: {{ motion_score }}. <br>
Length: {{ motion_length }}.
data:
image: "{{ states('sensor.snapshot_remote') }}{{ notify_image }}"
clickAction: "/lovelace/camera_driveway"
group: Driveway
Super thanks! I updated the code with camera.snapshot
and so far so good Will look into the code for file naming.
Wow! Your code was like finding a big safe full of money, you get super excited but not sure what to do with it So much useful stuff in there but itās gonna take some time for me to digest it I had no clue you can get all kind of information from the motion triggering. Is there a list somewhere with the variables that can be used?
Thank you so much for sharing!
I tend to use the homeassistant Developer Tools > State page to review entities and attributes and always build and test my template syntax in Developer Tools > Template. I do (still) build my automations in flat yaml files rather than using the user interface tools though as I find it easier to do things that way.
Smart, Iāll be better at looking there.
Can I ask you (or someone else) how you deal with privacy and the images that are created? As it is now, they are stored in config/www
and can be accessed by anyone. Is there a way to secure them and make them unreachable (I guess outside of www
but still make them show up in the notification?
Hmm - canāt say Iād ever realised that they could be accessed on the internal http link without authenticating via HA first but based on a quick test they can (if someone knows the full image path).
Looks like this as come up in discussion not too long ago: What the heck: config/www == local? - #25 by tom_l with the suggestion of using the new /media path for storage (Iāve not tried this).
I may consider moving mine down the road but Iāve a lot of items on my todo list at the moment - moving from a core venv install to core in docker, migrating from zwave to zwavejs.
Changing image storage location on my install is likely to be a Saturday grepping session when Iāve got docker stuff doneā¦
If you get anything working, please share.
A workaround would be to instead of showing a static image, a live stream would show in the notification. Would be so much useful, but Iām not having any luck getting it up and running.
@gr4z, I noticed that you struggeled to get the live stream in a notification, did you ever get that to work?
Edit:
I got the /media
folder to work when sending notifications. This way the images arenāt accessible if someone has the direct link. A bit more secure. This page helped me get it to work:
This probably explains the issue I am experiencing. I seem to get outdated images, and even after removing the files from the expected storage location and re-triggering the motion event, I get an old image. This was very confusing to me until reading this post.
Iām using the Home Assistant app on iOS, and need to figure out how to clear the cache for it. I am especially interested in doing it programmatically as part of my Node-Red flow that pops up a camera snapshot.
The easiest way to resolve image caching is to append a timestamp to the end of the captured image, making it unique. I work in YAML so set a variable with the image name as a first action in the automation and then reference that variable for the other actions.
I use a nightly cron job to clean images older than 14 days from the storage folder.
I got the
/media
folder to work when sending notifications. This way the images arenāt accessible if someone has the direct link. A bit more secure. This page helped me get it to work:
That link proved very useful - Iāve moved my notification images to a sub-directory of /media after testing it out as part of my prep to move to docker.
As part of the move I also tidied up my automations to use a folder_watcher to automatically update the last motion event image for the dashboard which removed the need for a file copy in the camera automation.
Just the venv->docker and zwave->zwavejs move to go now (all tested, just need a window to migrate with the time to bugfix if needed).
Hello all, clean install of HA and working very well, however im not able to find Unifi protect when i search for it under integrations. Any idea?
Have you installed the integration files using HACs or another method per https://github.com/briis/unifiprotect#installation?
The integration is not yet one of the core integrations included with a installation of HA.
Ah thank you
Thanks so much for this! Your component is why I dug in and started using Home Assistant (as of yesterday) I have a newb question if you donāt mind. Everything seems to be working great except I notice a good 10 second delay on the feed with this method. Is there any way to improve on that?
alias: Doorbell Nest Display
description: ''
trigger:
- platform: state
entity_id: binary_sensor.motion_front_door
to: 'on'
condition: []
action:
- data:
media_player: media_player.kitchen_display
service: camera.play_stream
entity_id: camera.front_door
- delay:
hours: 0
minutes: 0
seconds: 20
milliseconds: 0
- service: media_player.turn_off
data: {}
entity_id: media_player.kitchen_display
mode: single
Welcome to Home Assistant - hope you will enjoy it.
The Protect integration uses the stream
component built-in to Home Assistant, and that gives a 10-20 seconds delay in the stream. I assume it is due to conversion of the RTSP stream.
If you donāt need the Audio, you can disable all the RTSP streams in the Protect APP, and then restart Home Assistant. This will improve the video delay, but you loose the audio.
Thanks! It seems that the same automation doesnāt work after turning off the streams:
Logger: homeassistant.components.stream.worker
Source: components/stream/worker.py:83
Integration: Stream (documentation, issues)
First occurred: 8:11:13 AM (4 occurrences)
Last logged: 8:12:47 AM
Error opening stream rtsp://192.168.1.1:7447/MyFWLhUVZ9qhSXId
It will work in Lovelace, displaying the stream, in a Picture Glance card. I can see it still uses the RTSP stream, so you might need to restart HA. I am not sure it will work though, as the camera.play_stream
might require a real stream. I will play a little with it, to see if I can get it to work. Until then, enable the stream again in the Protect App, to at least get the stream with delay.
hey @briis
Iām using this with a G4 doorbell. I donāt like how the stock appās notification doesnāt send a thumbnail, by the time you get into the protect app, the person is gone.
So I successfully built an automation to push a notification to my mobile apps with a screenshot of the camera in HA. This notification has buttons for āview in HAā and āview in Protectā.
For āview in protectā, Iām trying to grab the intent, so that I can take the user straight to the doorbell live view, just like the protect app does. So I grabbed a logcat and found this intent:
03-03 15:25:08.880 1335 4546 D OemSceneCallBlock: isCallBlockedWithUidIntent { flg=0x1000c000 cmp=com.ubnt.unifi.protect/com.ubnt.activities.DashboardActivity (has extras) }, ResolveInfo{307d3d2 com.ubnt.unifi.protect/com.ubnt.activities.DashboardActivity m=0x0}
03-03 15:25:08.881 1335 4546 I ActivityTaskManager: START u0 {flg=0x1000c000 cmp=com.ubnt.unifi.protect/com.ubnt.activities.DashboardActivity (has extras)} from uid 10692 pid -1
03-03 15:25:08.887 1335 4546 E ANDR-PERF-JNI: com_qualcomm_qtiperformance_native_perf_io_prefetch_start
03-03 15:25:08.894 1335 4546 D ActivityTrigger: ActivityTrigger activityPauseTrigger
03-03 15:25:08.896 1630 1632 E ANDR-IOP: io prefetch is disabled
03-03 15:25:08.897 3796 3796 D Launcher: onPause# hashcode: 165350502
03-03 15:25:08.897 3796 3796 I ShelfLauncherCallbacks: onPause
03-03 15:25:08.898 3796 3961 I WeatherProvider: un-subscribe the weather callback:
03-03 15:25:08.898 1335 1402 D OpPowerConsumpStatsInjector: notifyPkgEvent
03-03 15:25:08.898 1335 1402 D OpRestartProcessManager: updateSelf : com.ubnt.unifi.protect, size : 30
03-03 15:25:08.900 12671 12671 W ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@2af5800
03-03 15:25:08.900 1335 4497 D OemSceneModeActivityStack: [scene] evaluateGameModes : gameMsg.arg1=0 gameMsg.arg2=1
03-03 15:25:08.901 1335 4497 D OpQuickReply: setQuickReplyResumed focusedApp AppWindowToken{986f755 token=Token{53defa7 ActivityRecord{83f10a3 u0 com.ubnt.unifi.protect/com.ubnt.activities.DashboardActivity t23672}}} pkgName com.ubnt.unifi.protect
(I changed around some numbers in case there is identifying info here)
Is there any chance you know how to make sense of this? I have no clue how to sort out which part of this is the āintentā
cheers!