diff --git a/custom_components/llmvision/__init__.py b/custom_components/llmvision/__init__.py index 01e5147..07aece5 100644 --- a/custom_components/llmvision/__init__.py +++ b/custom_components/llmvision/__init__.py @@ -36,6 +36,7 @@ TEMPERATURE, INCLUDE_FILENAME, EXPOSE_IMAGES, + EXPOSE_IMAGES_PERSIST, GENERATE_TITLE, SENSOR_ENTITY, ) @@ -251,6 +252,7 @@ def __init__(self, data_call): self.max_tokens = int(data_call.data.get(MAXTOKENS, 100)) self.include_filename = data_call.data.get(INCLUDE_FILENAME, False) self.expose_images = data_call.data.get(EXPOSE_IMAGES, False) + self.expose_images_persist = data_call.data.get(EXPOSE_IMAGES_PERSIST, False) self.generate_title = data_call.data.get(GENERATE_TITLE, False) self.sensor_entity = data_call.data.get(SENSOR_ENTITY) # ------------ Added during call ------------ @@ -308,11 +310,11 @@ async def video_analyzer(data_call): target_width=call.target_width, include_filename=call.include_filename, expose_images=call.expose_images, + expose_images_persist=call.expose_images_persist, 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 diff --git a/custom_components/llmvision/const.py b/custom_components/llmvision/const.py index 84d019a..2cc05bf 100644 --- a/custom_components/llmvision/const.py +++ b/custom_components/llmvision/const.py @@ -41,6 +41,7 @@ TEMPERATURE = 'temperature' INCLUDE_FILENAME = 'include_filename' EXPOSE_IMAGES = 'expose_images' +EXPOSE_IMAGES_PERSIST = 'expose_images_persist' GENERATE_TITLE = 'generate_title' SENSOR_ENTITY = 'sensor_entity' diff --git a/custom_components/llmvision/media_handlers.py b/custom_components/llmvision/media_handlers.py index dc02cc5..d71511e 100644 --- a/custom_components/llmvision/media_handlers.py +++ b/custom_components/llmvision/media_handlers.py @@ -318,13 +318,14 @@ 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, frigate_retry_attempts, frigate_retry_seconds): + async def add_videos(self, video_paths, event_ids, max_frames, target_width, include_filename, expose_images, expose_images_persist, 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" if not video_paths: video_paths = [] + processed_event_ids = [] if event_ids: for event_id in event_ids: try: @@ -348,14 +349,17 @@ async def add_videos(self, video_paths, event_ids, max_frames, target_width, inc f"Saved frigate clip to {clip_path} (temporarily)") # append to video_paths video_paths.append(clip_path) + processed_event_ids.append(event_id) except AttributeError as e: raise ServiceValidationError( f"Failed to fetch frigate clip {event_id}: {e}") if video_paths: _LOGGER.debug(f"Processing videos: {video_paths}") + video_count = 0 for video_path in video_paths: try: + current_event_id = processed_event_ids[video_count] video_path = video_path.strip() if os.path.exists(video_path): # create tmp dir to store extracted frames @@ -421,7 +425,10 @@ async def add_videos(self, video_paths, event_ids, max_frames, target_width, inc for frame_path, _ in sorted_frames: resized_image = await self.resize_image(image_path=frame_path, target_width=target_width) if expose_images: - await self._save_clip(image_path="/config/www/llmvision/" + frame_path.split("/")[-1], image_data=resized_image) + persist_filename = f"/config/www/llmvision/" + frame_path.split("/")[-1] + if expose_images_persist: + persist_filename = f"/config/www/llmvision/{current_event_id}-" + frame_path.split("/")[-1] + await self._save_clip(image_data=resized_image, image_path=persist_filename) self.client.add_frame( base64_image=resized_image, filename=video_path.split('/')[-1].split('.')[-2] + " (frame " + str(counter) + ")" if include_filename else "Video frame " + str(counter) diff --git a/custom_components/llmvision/services.yaml b/custom_components/llmvision/services.yaml index 64c2404..f430a87 100644 --- a/custom_components/llmvision/services.yaml +++ b/custom_components/llmvision/services.yaml @@ -238,6 +238,15 @@ video_analyzer: default: false selector: boolean: + expose_images_persist: + name: Persist Exposed Images + description: Normally exposed images are re-written with each new event. Setting this to true will include the Frigate eventID, if available, as part of the filename. If there is no + Frigate eventID, a guid will be used instead. + required: false + example: false + default: false + selector: + boolean: stream_analyzer: name: Stream Analyzer