Skip to content

Commit

Permalink
Merge branch 'main' into multi-request
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinfrlch authored Dec 26, 2024
2 parents e72cfa9 + d7335e0 commit ae0ee04
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ logger:
> These are planned features and ideas. They are subject to change and may not be implemented in the order listed or at all.
1. **HACS**: Include in HACS default repository
2. **Providers**: Support for Azure
For features added in previous versions, check the changelogs in the release notes.
Expand Down
4 changes: 3 additions & 1 deletion blueprints/event_summary.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ condition:
and ('camera.' + trigger.payload_json['after']['camera']|lower) in camera_entities_list
and ((object_types_list|length) == 0 or ((trigger.payload_json['after']['label']|lower) in object_types_list))
}}
{%else%}
true
{% endif %}
Expand Down Expand Up @@ -429,4 +431,4 @@ action:
group: "{{group}}"
interruption-level: passive

- delay: '00:{{cooldown|int}}:00'
- delay: '00:{{cooldown|int}}:00'
10 changes: 9 additions & 1 deletion custom_components/llmvision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
IMAGE_ENTITY,
VIDEO_FILE,
EVENT_ID,
FRIGATE_RETRY_ATTEMPTS,
FRIGATE_RETRY_SECONDS,
INTERVAL,
DURATION,
MAX_FRAMES,
Expand Down Expand Up @@ -241,6 +243,8 @@ def __init__(self, data_call):
"\n") if data_call.data.get(EVENT_ID) else None
self.interval = int(data_call.data.get(INTERVAL, 2))
self.duration = int(data_call.data.get(DURATION, 10))
self.frigate_retry_attempts = int(data_call.data.get(FRIGATE_RETRY_ATTEMPTS, 2))
self.frigate_retry_seconds = int(data_call.data.get(FRIGATE_RETRY_SECONDS, 1))
self.max_frames = int(data_call.data.get(MAX_FRAMES, 3))
self.target_width = data_call.data.get(TARGET_WIDTH, 3840)
self.temperature = float(data_call.data.get(TEMPERATURE, 0.3))
Expand Down Expand Up @@ -291,6 +295,7 @@ async def video_analyzer(data_call):
start = dt_util.now()
call = ServiceCallData(data_call).get_service_call_data()
call.message = "The attached images are frames from a video. " + call.message

request = Request(hass,
message=call.message,
max_tokens=call.max_tokens,
Expand All @@ -302,9 +307,12 @@ async def video_analyzer(data_call):
max_frames=call.max_frames,
target_width=call.target_width,
include_filename=call.include_filename,
expose_images=call.expose_images
expose_images=call.expose_images,
frigate_retry_attempts=call.frigate_retry_attempts,
frigate_retry_seconds=call.frigate_retry_seconds
)
response = await request.call(call)

await _remember(hass, call, start, response)
return response

Expand Down
2 changes: 2 additions & 0 deletions custom_components/llmvision/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
EVENT_ID = 'event_id'
INTERVAL = 'interval'
DURATION = 'duration'
FRIGATE_RETRY_ATTEMPTS = 'frigate_retry_attempts'
FRIGATE_RETRY_SECONDS = 'frigate_retry_seconds'
MAX_FRAMES = 'max_frames'
TEMPERATURE = 'temperature'
INCLUDE_FILENAME = 'include_filename'
Expand Down
10 changes: 6 additions & 4 deletions custom_components/llmvision/media_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ async def add_images(self, image_entities, image_paths, target_width, include_fi
raise ServiceValidationError(f"Error: {e}")
return self.client

async def add_videos(self, video_paths, event_ids, max_frames, target_width, include_filename, expose_images):
async def add_videos(self, video_paths, event_ids, max_frames, target_width, include_filename, expose_images, frigate_retry_attempts, frigate_retry_seconds):
"""Wrapper for client.add_frame for videos"""
tmp_clips_dir = f"/config/custom_components/{DOMAIN}/tmp_clips"
tmp_frames_dir = f"/config/custom_components/{DOMAIN}/tmp_frames"
Expand All @@ -330,8 +330,9 @@ async def add_videos(self, video_paths, event_ids, max_frames, target_width, inc
try:
base_url = get_url(self.hass)
frigate_url = base_url + "/api/frigate/notifications/" + event_id + "/clip.mp4"
clip_data = await self._fetch(frigate_url)

clip_data = await self._fetch(frigate_url, max_retries=frigate_retry_attempts, retry_delay=frigate_retry_seconds)

if not clip_data:
raise ServiceValidationError(
f"Failed to fetch frigate clip {event_id}")
Expand Down Expand Up @@ -371,8 +372,9 @@ async def add_videos(self, video_paths, event_ids, max_frames, target_width, inc
ffmpeg_cmd = [
"ffmpeg",
"-i", video_path,
"-vf", f"fps=1/{interval},select='eq(n\\,0)+not(mod(n\\,{interval}))'", os.path.join(
tmp_frames_dir, "frame%04d.jpg")
"-vf", f"fps=fps='source_fps',select='eq(n\\,0)+not(mod(n\\,{interval}))'",
"-fps_mode", "passthrough",
os.path.join(tmp_frames_dir, "frame%04d.jpg")
]
# Run ffmpeg command
await self.hass.loop.run_in_executor(None, os.system, " ".join(ffmpeg_cmd))
Expand Down
24 changes: 24 additions & 0 deletions custom_components/llmvision/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,30 @@ video_analyzer:
selector:
text:
multiline: true
frigate_retry_attempts:
name: Frigate Retry Attempts
description: How many times to retry fetching the video clip from Frigate. Clips are not always available from Frigate as soon as the event has ended.
Slower machines or longer clips may need additional attempts. Increase this if you see errors fetching the clips from Frigate in your automation traces.
required: false
example: 2
default: 2
selector:
number:
min: 1
max: 10
step: 1
frigate_retry_seconds:
name: Frigate Retry Seconds
description: How long to wait between retries to fetch the video clip from Frigate. Clips are not always available from Frigate as soon as the event has ended.
Slower machines or longer clips may need additional attempts. Increase this if you see errors fetching the clips from Frigate in your automation traces.
required: false
example: 1
default: 1
selector:
number:
min: 1
max: 10
step: 1
max_frames:
name: Max Frames
description: How many frames to analyze. Picks frames with the most movement.
Expand Down

0 comments on commit ae0ee04

Please sign in to comment.