parent
71ffa6120b
commit
825b26c800
@ -0,0 +1,185 @@
|
||||
######################################################################
|
||||
# @CCOSTAN - Follow Me on X
|
||||
# For more info visit https://www.vcloudinfo.com/click-here
|
||||
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
|
||||
# -------------------------------------------------------------------
|
||||
# Frigate - local front-door package state classification
|
||||
# Related Issue: 1984
|
||||
# Classify the white porch floor locally; keep package reminders shared.
|
||||
# -------------------------------------------------------------------
|
||||
# Notes: Frigate 0.18 classifies clear/package_present with a trained
|
||||
# custom model, motion checks, a 15-second interval, and 3-state consensus.
|
||||
# Notes: Either crop can mark a package present; both must report clear
|
||||
# before clearing it. The second crop covers partial doorstep-edge boxes.
|
||||
# Notes: Existing package/cans binary-sensor identities stay compatible.
|
||||
# LLM Vision is removed. Last sync records state updates, not every
|
||||
# inference; the status button reads the last verified state.
|
||||
# Notes: Unknown/unavailable classifications never clear a package.
|
||||
# Notes: Garage is non-production and disabled. The reflective X is gone;
|
||||
# any future classifier must use the actual bins in the upper-right.
|
||||
# Docs: https://docs.frigate.video/configuration/custom_classification/state_classification/
|
||||
# Original LLM Vision experiment video: https://youtu.be/nAhCezFetvI
|
||||
# Notification icons video: https://youtu.be/TMfdxv-WprM
|
||||
# Notification icons blog: https://www.vcloudinfo.com/2026/10/home-assistant-ios-notification-icons.html
|
||||
######################################################################
|
||||
|
||||
input_button:
|
||||
front_door_package_check:
|
||||
name: "Frigate: Front door package status"
|
||||
icon: mdi:package-variant-closed-check
|
||||
|
||||
input_boolean:
|
||||
garbage_cans_out:
|
||||
name: "Garbage Cans Out"
|
||||
icon: mdi:trash-can
|
||||
front_door_packages_present:
|
||||
name: "Front Door Packages Present"
|
||||
icon: mdi:package-variant-closed
|
||||
|
||||
input_text:
|
||||
front_door_package_classification:
|
||||
name: "Frigate front door classification"
|
||||
max: 255
|
||||
|
||||
input_datetime:
|
||||
front_door_package_last_sync:
|
||||
name: "Frigate front door last state sync"
|
||||
has_date: true
|
||||
has_time: true
|
||||
|
||||
template:
|
||||
- binary_sensor:
|
||||
- name: "Garbage Cans Out"
|
||||
unique_id: llmvision_garbage_cans_out
|
||||
device_class: presence
|
||||
state: "{{ is_state('input_boolean.garbage_cans_out', 'on') }}"
|
||||
attributes:
|
||||
classification_status: not_configured
|
||||
source_camera: camera.garagecam
|
||||
|
||||
- name: "Front Door Packages Present"
|
||||
unique_id: llmvision_front_door_packages_present
|
||||
availability: >-
|
||||
{{ states('sensor.frontdoorbell_front_door_packages_classification')
|
||||
in ['clear', 'package_present']
|
||||
and states('sensor.frontdoorbell_front_door_package_edge_classification')
|
||||
in ['clear', 'package_present'] }}
|
||||
device_class: presence
|
||||
state: "{{ is_state('input_boolean.front_door_packages_present', 'on') }}"
|
||||
attributes:
|
||||
last_sync: "{{ states('input_datetime.front_door_package_last_sync') }}"
|
||||
classification: "{{ states('input_text.front_door_package_classification') }}"
|
||||
source_camera: camera.frontdoorbell
|
||||
source_classifier: sensor.frontdoorbell_front_door_packages_classification
|
||||
source_classifier_edge: sensor.frontdoorbell_front_door_package_edge_classification
|
||||
classifier_state: "{{ states('sensor.frontdoorbell_front_door_packages_classification') }}"
|
||||
classifier_edge_state: "{{ states('sensor.frontdoorbell_front_door_package_edge_classification') }}"
|
||||
|
||||
automation:
|
||||
- alias: Frigate - Front door packages
|
||||
id: 8647b555-7ba0-41d5-98de-cfd3094e5b4f
|
||||
description: "Sync Frigate's verified local porch state to the existing package helper."
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- sensor.frontdoorbell_front_door_packages_classification
|
||||
- sensor.frontdoorbell_front_door_package_edge_classification
|
||||
from: null
|
||||
id: classification
|
||||
- platform: homeassistant
|
||||
event: start
|
||||
id: startup
|
||||
- platform: state
|
||||
entity_id: input_button.front_door_package_check
|
||||
id: manual_check
|
||||
variables:
|
||||
labels: >-
|
||||
{{ [states('sensor.frontdoorbell_front_door_packages_classification'),
|
||||
states('sensor.frontdoorbell_front_door_package_edge_classification')] }}
|
||||
classification: "{{ 'package_present' if 'package_present' in labels else 'clear' }}"
|
||||
condition:
|
||||
- condition: state
|
||||
entity_id:
|
||||
- sensor.frontdoorbell_front_door_packages_classification
|
||||
- sensor.frontdoorbell_front_door_package_edge_classification
|
||||
state:
|
||||
- clear
|
||||
- package_present
|
||||
action:
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id:
|
||||
- sensor.frontdoorbell_front_door_packages_classification
|
||||
- sensor.frontdoorbell_front_door_package_edge_classification
|
||||
state: package_present
|
||||
match: any
|
||||
then:
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
else:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
- service: input_text.set_value
|
||||
target:
|
||||
entity_id: input_text.front_door_package_classification
|
||||
data:
|
||||
value: "{{ classification }}"
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.front_door_package_last_sync
|
||||
data:
|
||||
datetime: "{{ now() }}"
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: PACKAGES
|
||||
message: "Local Frigate package state synced: {{ classification }}."
|
||||
- if:
|
||||
- condition: trigger
|
||||
id: manual_check
|
||||
then:
|
||||
- service: script.notify_engine
|
||||
data:
|
||||
title: Front door package status
|
||||
notification_icon: mdi:package-variant-closed-check
|
||||
color: '#6A1B9A'
|
||||
value1: "Frigate's last verified porch state is {{ classification | replace('_', ' ') }}."
|
||||
who: carlo
|
||||
group: information
|
||||
level: active
|
||||
camera_entity: camera.frontdoorbell
|
||||
|
||||
- alias: Frigate - Front door package notify
|
||||
id: 0ddf0fb5-4600-4eff-9236-95b2af3739a6
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
to: 'on'
|
||||
for: "00:01:00"
|
||||
action:
|
||||
- variables:
|
||||
package_message: >-
|
||||
Front door camera thinks a package may be waiting at the door.
|
||||
notify_target: >-
|
||||
{% if is_state('group.family', 'home') %}
|
||||
family
|
||||
{% else %}
|
||||
carlo
|
||||
{% endif %}
|
||||
- service: script.notify_engine
|
||||
data:
|
||||
title: Package check
|
||||
notification_icon: mdi:package-variant-closed-check
|
||||
color: '#6A1B9A'
|
||||
value1: "{{ package_message }}"
|
||||
who: "{{ notify_target }}"
|
||||
group: information
|
||||
level: active
|
||||
camera_entity: camera.frontdoorbell
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: PACKAGES
|
||||
message: "{{ package_message }}"
|
||||
@ -1,302 +0,0 @@
|
||||
######################################################################
|
||||
# @CCOSTAN - Follow Me on X
|
||||
# For more info visit https://www.vcloudinfo.com/click-here
|
||||
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
|
||||
# -------------------------------------------------------------------
|
||||
# LLM Vision - garage cans and front-door package checks
|
||||
# Related Issue: 1773
|
||||
# Trigger with input_button.llmvision_garbage_check, input_button.llmvision_front_door_package_check, or front door person activity to update vision-backed package sensors.
|
||||
# -------------------------------------------------------------------
|
||||
# Notes: LLMVision analyzes camera.garagecam; expects strict "on"/"off" output.
|
||||
# Notes: Front-door package detection waits 3 minutes after person
|
||||
# activity, skips routine relocks unless a package is already present,
|
||||
# and rate-limits/downscales OpenAI vision calls for cost control.
|
||||
# Notes: The garage analyzer uses gpt-5.4-nano and remains manual;
|
||||
# the front-door analyzer uses gpt-4.1-mini for reliable package detection.
|
||||
# Docs: https://llmvision.gitbook.io/getting-started/usage/image-analyzer
|
||||
# Video: https://youtu.be/nAhCezFetvI
|
||||
# Notification icons video: https://youtu.be/TMfdxv-WprM
|
||||
# Notification icons blog: https://www.vcloudinfo.com/2026/10/home-assistant-ios-notification-icons.html
|
||||
######################################################################
|
||||
|
||||
input_button:
|
||||
llmvision_garbage_check:
|
||||
name: "LLM Vision: Garage cans check"
|
||||
icon: mdi:delete-variant
|
||||
llmvision_front_door_package_check:
|
||||
name: "LLM Vision: Front door package check"
|
||||
icon: mdi:package-variant-closed-check
|
||||
|
||||
input_boolean:
|
||||
garbage_cans_out:
|
||||
name: "Garbage Cans Out"
|
||||
icon: mdi:trash-can
|
||||
front_door_packages_present:
|
||||
name: "Front Door Packages Present"
|
||||
icon: mdi:package-variant-closed
|
||||
|
||||
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
|
||||
llmvision_front_door_last_response:
|
||||
name: "LLM Vision front door response"
|
||||
max: 255
|
||||
llmvision_front_door_last_keyframe:
|
||||
name: "LLM Vision front door key frame"
|
||||
max: 255
|
||||
|
||||
input_datetime:
|
||||
llmvision_garbage_last_run:
|
||||
name: "LLM Vision garage last run"
|
||||
has_date: true
|
||||
has_time: true
|
||||
llmvision_front_door_last_run:
|
||||
name: "LLM Vision front door last run"
|
||||
has_date: true
|
||||
has_time: true
|
||||
|
||||
template:
|
||||
- binary_sensor:
|
||||
- name: "Garbage Cans Out"
|
||||
unique_id: llmvision_garbage_cans_out
|
||||
device_class: presence
|
||||
state: "{{ is_state('input_boolean.garbage_cans_out', '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
|
||||
|
||||
- name: "Front Door Packages Present"
|
||||
unique_id: llmvision_front_door_packages_present
|
||||
device_class: presence
|
||||
state: "{{ is_state('input_boolean.front_door_packages_present', 'on') }}"
|
||||
attributes:
|
||||
last_run: "{{ states('input_datetime.llmvision_front_door_last_run') }}"
|
||||
last_response: "{{ states('input_text.llmvision_front_door_last_response') }}"
|
||||
last_key_frame: "{{ states('input_text.llmvision_front_door_last_keyframe') }}"
|
||||
source_camera: camera.frontdoorbell
|
||||
|
||||
automation:
|
||||
- alias: LLM Vision - Garbage cans out
|
||||
id: d88a2e6d-78f3-4bb7-9d9f-c4d06e6eb5a9
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: input_button.llmvision_garbage_check
|
||||
variables:
|
||||
prompt_text: >
|
||||
Examine the image. I have taped a reflective X on the right wall. Look for the reflective X on the right wall. If you clearly see the X, respond exactly: on. If you cannot see the X, respond exactly: off. No other words.
|
||||
action:
|
||||
- service: llmvision.data_analyzer
|
||||
response_variable: llmvision_result
|
||||
data:
|
||||
provider: !secret llmvision_provider_entry
|
||||
model: gpt-5.4-nano
|
||||
message: "{{ prompt_text }}"
|
||||
sensor_entity: input_boolean.garbage_cans_out
|
||||
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() }}"
|
||||
|
||||
- alias: LLM Vision - Front door packages
|
||||
id: 8647b555-7ba0-41d5-98de-cfd3094e5b4f
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: numeric_state
|
||||
entity_id: sensor.frontdoorbell_person_active_count_2
|
||||
above: 0
|
||||
id: person_count
|
||||
- platform: state
|
||||
entity_id: lock.front_door
|
||||
from: unlocked
|
||||
to: locked
|
||||
id: front_door_locked
|
||||
- platform: state
|
||||
entity_id: input_button.llmvision_front_door_package_check
|
||||
id: manual_check
|
||||
variables:
|
||||
trigger_source: >-
|
||||
{% if trigger.id == 'manual_check' %}
|
||||
manual button
|
||||
{% elif trigger.id == 'front_door_locked' %}
|
||||
front door relock
|
||||
{% else %}
|
||||
front door person activity
|
||||
{% endif %}
|
||||
prompt_text: >-
|
||||
Examine these front door camera frames for delivery packages. Focus on the porch and doorstep area,
|
||||
especially the lower-right and bottom-right edge near the door. Treat cardboard boxes, padded mailers,
|
||||
poly bags, shopping bags, and white shipping bags as packages. A package can be partially cut off by
|
||||
the edge of the image or timestamp overlay and should still count as visible if part of the bag, box,
|
||||
label, or mailer is visible on the porch. Ignore the street, cars, landscaping, and anything not
|
||||
resting on the porch or doorstep. Respond exactly: on or off. No other words.
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ trigger.id == 'person_count' }}"
|
||||
sequence:
|
||||
- delay: "00:03:00"
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ trigger.id == 'front_door_locked' }}"
|
||||
sequence:
|
||||
- delay: "00:00:20"
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set last = states('input_datetime.llmvision_front_door_last_run') %}
|
||||
{% set minutes_since_last = 999 if last in ['unknown', 'unavailable', 'none', ''] else ((as_timestamp(now()) - as_timestamp(last)) / 60) | int(999) %}
|
||||
{{ trigger.id == 'manual_check'
|
||||
or (trigger.id == 'person_count' and minutes_since_last >= 15)
|
||||
or (trigger.id == 'front_door_locked'
|
||||
and is_state('input_boolean.front_door_packages_present', 'on')
|
||||
and minutes_since_last >= 5) }}
|
||||
- service: llmvision.stream_analyzer
|
||||
response_variable: llmvision_result
|
||||
data:
|
||||
provider: !secret llmvision_provider_entry
|
||||
model: gpt-4.1-mini
|
||||
message: "{{ prompt_text }}"
|
||||
image_entity:
|
||||
- camera.frontdoorbell
|
||||
duration: 4
|
||||
max_frames: 3
|
||||
include_filename: false
|
||||
target_width: 1280
|
||||
max_tokens: 32
|
||||
expose_images: true
|
||||
- variables:
|
||||
normalized_response: "{{ llmvision_result.response_text | default('') | trim | lower }}"
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ normalized_response in ['on', 'yes', 'true']
|
||||
or normalized_response.startswith('on')
|
||||
or normalized_response.startswith('yes') }}
|
||||
sequence:
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ normalized_response in ['off', 'no', 'false']
|
||||
or normalized_response.startswith('off')
|
||||
or normalized_response.startswith('no') }}
|
||||
sequence:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
- service: input_text.set_value
|
||||
target:
|
||||
entity_id: input_text.llmvision_front_door_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_front_door_last_keyframe
|
||||
data:
|
||||
value: "{{ llmvision_result.key_frame }}"
|
||||
default:
|
||||
- service: input_text.set_value
|
||||
target:
|
||||
entity_id: input_text.llmvision_front_door_last_keyframe
|
||||
data:
|
||||
value: ""
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.llmvision_front_door_last_run
|
||||
data:
|
||||
datetime: "{{ now() }}"
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: PACKAGES
|
||||
message: >-
|
||||
Front door package vision check ran via {{ trigger_source }}
|
||||
and returned {{ llmvision_result.response_text | default(states('input_boolean.front_door_packages_present')) | lower }}.
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ trigger.id == 'manual_check' }}"
|
||||
sequence:
|
||||
- service: script.notify_engine
|
||||
data:
|
||||
title: Front door package test
|
||||
notification_icon: mdi:package-variant-closed-check
|
||||
color: '#6A1B9A'
|
||||
value1: >-
|
||||
LLM Vision returned {{ llmvision_result.response_text | default(states('input_boolean.front_door_packages_present')) | lower }}
|
||||
for the front door package check.
|
||||
who: carlo
|
||||
group: information
|
||||
level: active
|
||||
camera_entity: camera.frontdoorbell
|
||||
|
||||
- alias: LLM Vision - Front door package notify
|
||||
id: 0ddf0fb5-4600-4eff-9236-95b2af3739a6
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
to: 'on'
|
||||
for: "00:01:00"
|
||||
action:
|
||||
- variables:
|
||||
package_message: >-
|
||||
Front door camera thinks a package may be waiting at the door.
|
||||
notify_target: >-
|
||||
{% if is_state('group.family', 'home') %}
|
||||
family
|
||||
{% else %}
|
||||
carlo
|
||||
{% endif %}
|
||||
- service: script.notify_engine
|
||||
data:
|
||||
title: Package check
|
||||
notification_icon: mdi:package-variant-closed-check
|
||||
color: '#6A1B9A'
|
||||
value1: "{{ package_message }}"
|
||||
who: "{{ notify_target }}"
|
||||
group: information
|
||||
level: active
|
||||
camera_entity: camera.frontdoorbell
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: PACKAGES
|
||||
message: "{{ package_message }}"
|
||||
@ -0,0 +1,96 @@
|
||||
# Local Frigate package state classification
|
||||
|
||||
Tracking: [issue #1984](https://github.com/CCOSTAN/Home-AssistantConfig/issues/1984).
|
||||
|
||||
The front-door package flow now uses Frigate 0.18 custom state classification. Two camera crops look at the white porch floor where deliveries are placed. Inference runs locally; this flow makes no LLM Vision or OpenAI calls. The existing Home Assistant package helpers, dashboard references, snapshot notifications, and shared notification engine remain in use.
|
||||
|
||||
The source is [frigate_classification.yaml](../config/packages/frigate_classification.yaml). The package/cans binary sensors keep their internal registry identities so existing consumers remain compatible. The package status and diagnostic helpers use neutral names; obsolete LLM Vision helpers and the disabled garage automation are removed.
|
||||
|
||||
## Frigate setup
|
||||
|
||||
Train two separate state classifiers through Frigate's Classification UI. Use the same two labels, `clear` and `package_present`, for each model. These are camera-specific models, not a generic pretrained package detector. Adjust the crops to match your own camera and delivery area.
|
||||
|
||||
```yaml
|
||||
classification:
|
||||
custom:
|
||||
front_door_packages:
|
||||
threshold: 0.9
|
||||
save_attempts: 200
|
||||
state_config:
|
||||
motion: true
|
||||
interval: 15
|
||||
cameras:
|
||||
frontdoorbell:
|
||||
crop: [0.10, 0.74, 1.0, 1.0]
|
||||
front_door_package_edge:
|
||||
threshold: 0.9
|
||||
save_attempts: 200
|
||||
state_config:
|
||||
motion: true
|
||||
interval: 15
|
||||
cameras:
|
||||
frontdoorbell:
|
||||
crop: [0.70, 0.74, 1.0, 1.0]
|
||||
```
|
||||
|
||||
The broad crop covers the white floor. The narrower crop gives partially visible boxes near the bottom-right edge more image detail. The timestamp is outside both crops.
|
||||
|
||||
Label real deliveries, cardboard boxes, shipping bags, partial packages, empty floor, shadows, people walking through, and people carrying packages without placing them down. Include day and night images and train after categorizing examples. Keep household images and generated models private. This implementation seeded each model with 46 examples: 15 package-present and 31 clear.
|
||||
|
||||
Frigate checks on motion and every 15 seconds. Its state classifier requires three matching confident observations before publishing a state change, with follow-up verification checks while a change is pending. Low-confidence predictions do not publish a new state; they preserve the previous verified state. The 0.9 threshold is an acceptance setting, not a measured accuracy percentage.
|
||||
|
||||
See the [official state-classification guide](https://docs.frigate.video/configuration/custom_classification/state_classification/).
|
||||
|
||||
## Home Assistant behavior
|
||||
|
||||
The Frigate integration supplies these entities:
|
||||
|
||||
- `sensor.frontdoorbell_front_door_packages_classification`
|
||||
- `sensor.frontdoorbell_front_door_package_edge_classification`
|
||||
|
||||
Both must have valid labels before the adapter changes the existing helper. Either crop reporting `package_present` turns `input_boolean.front_door_packages_present` on. Both reporting `clear` turn it off. An unknown or unavailable source leaves the helper unchanged and makes `binary_sensor.front_door_packages_present` unavailable.
|
||||
|
||||
The existing one-minute positive-state hold, family/Carlo routing, package icon, camera attachment, and Activity Feed logging are preserved. Continuous local classification replaces the former person/lock-triggered cloud capture, three-minute wait, and API rate limit.
|
||||
|
||||
`input_button.front_door_package_check` reports the last verified classifier state; it does not force a new camera inference. `input_datetime.front_door_package_last_sync` records the latest successful state synchronization, not every inference. `input_text.front_door_package_classification` records the synchronized label. Obsolete key-frame helpers are removed; notifications still use the camera image.
|
||||
|
||||
Create/reload the Frigate integration after adding classifiers. If a new classification sensor stays `Unknown`, ensure it receives a fresh classifier result before enabling the adapter. Frigate publishes classification changes without MQTT retention; the integration restores previously known states, but a newly discovered sensor can miss the initial result. Disabling and re-enabling that classifier through the supported config API after discovery lets it establish a fresh verified state. Do not publish invented classifier labels to initialize production.
|
||||
|
||||
LLM Vision's provider/settings entries and HACS component are removed, along with its old helpers, update entity, provider reference, and timeline artifacts, including the orphaned old cans-in registry entry. A private backup was retained before cleanup. The garage remains non-production with no classifier or active automation: its reflective X marker is gone. A future garage classifier must train on the actual cans in the upper-right image area and confirm how present/absent maps to cans-out semantics.
|
||||
|
||||
## Timestamp and motion mask
|
||||
|
||||
The camera bridge exposes a timestamp on/off control, with no position control. The original camera timestamp is disabled, and the Frigate/go2rtc source applies a top-left overlay. The Wyze app therefore has no burned-in timestamp; Frigate and its Home Assistant streams include the replacement.
|
||||
|
||||
For a go2rtc FFmpeg video source, append a drawtext filter using a font available in the container. This example uses a placeholder source stream:
|
||||
|
||||
```text
|
||||
ffmpeg:doorbell_raw#video=h264#drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:fontsize=38:fontcolor=white:borderw=2:bordercolor=black:x=20:y=20:text=%{localtime}
|
||||
```
|
||||
|
||||
This encodes the source video, so verify CPU use, live playback, recording, and any audio requirements for your camera. Keep existing compatible presentation streams downstream of the annotated source. Confirm the container's local time matches the desired timezone.
|
||||
|
||||
The existing timestamp motion mask moves to the top-left area (`0,0,0.345,0,0.345,0.045,0,0.045` for this portrait image). Keep other masks unchanged and adapt this polygon to your own timestamp width and camera resolution. Removing the old lower-right overlay and mask exposes the doorstep edge.
|
||||
|
||||
## Validation and remaining checks
|
||||
|
||||
The Frigate configuration and Home Assistant configuration passed validation. After the cutover restart, both classifier states restored as clear and the startup automation completed successfully. No LLM Vision config entries, services, or installed HACS component remain. Both live classification sensors report `clear` on the empty porch; a completed automation trace confirms helper synchronization. The existing mobile dashboard displays Packages: CLEAR. Notification automation remains enabled and no garage classifier or automation is enabled.
|
||||
|
||||
An isolated replay through Frigate's native classifier confirms clear -> package_present -> clear after three confident observations, and no new publication through low-confidence frames. These replay labels were never injected into production MQTT. Replay evaluation uses real historical images. Difficult tall and partly visible boxes initially failed and were moved into the training/calibration data, so they are not independent test results. The final separate check contains 28 clear frames and one unseen shipping-bag delivery. The broad model's top label matches all 29; the edge model has one wrong label below the acceptance threshold, so it does not publish that prediction. Some clear frames fall below threshold in both models. This small set does not establish production accuracy or removal reliability. Per-crop inference measured roughly 5-6 ms on the current host; this is not end-to-end alert latency.
|
||||
|
||||
Before calling the replacement proven, verify:
|
||||
|
||||
- A new delivery produces a stable present state and one notification.
|
||||
- A stationary package remains present through lighting changes.
|
||||
- Pickup/removal produces clear from both crops.
|
||||
- Night, white mailers, shadows, occlusion, and small edge packages behave correctly.
|
||||
- Camera/MQTT outages and recovery preserve safe state and resume updates.
|
||||
- New errors are categorized in Frigate and used for retraining.
|
||||
|
||||
## Rollback and future work
|
||||
|
||||
Retain the prior package YAML, Frigate configuration, and protected Home Assistant backup privately. To return to LLM Vision, reinstall its HACS component and configure the provider again, then restore the prior automation configuration and validate before reloading. The pre-removal backup also retains the removed integration configuration. Timestamp rollback removes the overlay, re-enables the camera timestamp, and restores its original mask. Use supported integration/configuration workflows; do not edit Home Assistant storage or Frigate model-cache files manually.
|
||||
|
||||
OpenAI Decisions remains an optional verification experiment in issue #1984. It is unnecessary for this local implementation and was not enabled or benchmarked. A candidate-only verifier cannot catch a package missed by the local classifier, so any later verification design should account for reconciliation too.
|
||||
|
||||
A future blog/video can show the original LLM Vision experiment, camera crops, labeling/training, the timestamp change, difficult cases, and measured real delivery/removal results. The [original video](https://youtu.be/nAhCezFetvI) documents the earlier cloud-based approach.
|
||||
Loading…
Reference in new issue