diff --git a/config/packages/llmvision.yaml b/config/packages/llmvision.yaml new file mode 100644 index 00000000..eb30fc30 --- /dev/null +++ b/config/packages/llmvision.yaml @@ -0,0 +1,87 @@ +# LLM Vision test package: checks the garage camera for garbage cans in the upper-right corner. +# Trigger with input_button.llmvision_garbage_check to update input_boolean.garbage_cans_in. + +input_button: + llmvision_garbage_check: + name: "LLM Vision: Garage cans check" + icon: mdi:delete-variant + +input_boolean: + garbage_cans_in: + name: "Garbage cans in upper right" + icon: mdi:trash-can + +input_text: + llmvision_garbage_last_response: + name: "LLM Vision garage response" + max: 255 + llmvision_garbage_last_keyframe: + name: "LLM Vision garage key frame" + max: 255 + +input_datetime: + llmvision_garbage_last_run: + name: "LLM Vision garage last run" + has_date: true + has_time: true + +template: + - binary_sensor: + - name: "Garbage cans in" + unique_id: llmvision_garbage_cans_in + device_class: presence + state: "{{ is_state('input_boolean.garbage_cans_in', 'on') }}" + attributes: + last_run: "{{ states('input_datetime.llmvision_garbage_last_run') }}" + last_response: "{{ states('input_text.llmvision_garbage_last_response') }}" + last_key_frame: "{{ states('input_text.llmvision_garbage_last_keyframe') }}" + source_camera: camera.garagecam + +automation: + - alias: LLM Vision - Garage cans upper right + id: d88a2e6d-78f3-4bb7-9d9f-c4d06e6eb5a9 + mode: restart + trigger: + - platform: state + entity_id: input_button.llmvision_garbage_check + variables: + prompt_text: > + Examine ONLY the upper-right quadrant of the image (top half + right half). Ignore everything else (car, floor text, door, bikes, bottles, bags). If you see a black garbage can in that upper-right quadrant, respond exactly "on". If none are present there, respond exactly "off". Do not add any other words. + action: + - service: llmvision.data_analyzer + response_variable: llmvision_result + data: + provider: !secret llmvision_provider_entry + model: gpt-4o-mini + message: "{{ prompt_text }}" + sensor_entity: input_boolean.garbage_cans_in + image_entity: + - camera.garagecam + include_filename: false + target_width: 1280 + max_tokens: 16 + expose_images: true + - service: input_text.set_value + target: + entity_id: input_text.llmvision_garbage_last_response + data: + value: "{{ (llmvision_result.response_text | default('unknown'))[:250] }}" + - choose: + - conditions: "{{ llmvision_result is defined and llmvision_result.key_frame is defined }}" + sequence: + - service: input_text.set_value + target: + entity_id: input_text.llmvision_garbage_last_keyframe + data: + value: "{{ llmvision_result.key_frame }}" + default: + - service: input_text.set_value + target: + entity_id: input_text.llmvision_garbage_last_keyframe + data: + value: "" + - service: input_datetime.set_datetime + target: + entity_id: input_datetime.llmvision_garbage_last_run + data: + datetime: "{{ now() }}" diff --git a/config/templates/speech/briefing.yaml b/config/templates/speech/briefing.yaml index ce3b3110..40e62be5 100755 --- a/config/templates/speech/briefing.yaml +++ b/config/templates/speech/briefing.yaml @@ -35,11 +35,8 @@ [Here is the current weather outside] {% set aq_description = state_attr('sensor.bear_stone_common_air_quality_index', 'description') | default('') %} {% set aq_index = states('sensor.bear_stone_common_air_quality_index') | int(0) %} - {% if aq_description %} - Air Quality: {{ aq_description }} - {% endif %} - {% if aq_index >= 150 %} - [Air quality is unhealthy; limit outdoor activity] + {% if aq_index >= 15 %} + [Air Quality: {{ aq_description }}] {% endif %} {% set pirateweather_metrics = states.sensor | selectattr('entity_id','search','pirateweather')