I cobbled together a way to track how many cars are driving in the bikelane outside of my place using Frigate, a bit of command line / ffmpeg, and Apex charts cards.
Edit: Happy to share code if there is interest.
Edit 2: There is interest. Progressively adding detail.
I used Frigate add-on and integration. Here is my Frigate config;
Frigate Config:
environment_vars:
LIBVA_DRIVER_NAME: i965 # Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz. It includes an Intel HD Graphics 4000 iGPU, which belongs to Intel Gen7 graphics.
ffmpeg:
global_args: -hide_banner -loglevel debug -threads 4
hwaccel_args: -hwaccel vaapi -hwaccel_device /dev/dri/renderD128
input_args: preset-rtsp-generic
output_args:
detect: -threads 4 -f rawvideo -pix_fmt yuv420p
record: preset-record-generic
retry_interval: 5
# ffmpeg:
# hwaccel_args: preset-vaapi # Correct for legacy Intel GPUs (Gen1–Gen7)
detectors:
coral:
type: edgetpu
device: usb
logger:
default: debug
mqtt:
enabled: true
host: homeassistant
port: xxxx
topic_prefix: frigate
client_id: frigate
user: XXXXX
password: XXXXX
timestamp_style:
position: tl # "tl" (top left), "tr" (top right), "bl" (bottom left), "br" (bottom right)
format: '%d/%m/%Y %H:%M:%S'
color:
red: 255
green: 255
blue: 255
thickness: 2
effect: solid # solid , shadow
detect:
enabled: false
motion:
enabled: false
record:
enabled: true
retain:
days: 1
mode: all
alerts:
pre_capture: 1 # secs
post_capture: 1 # secs
retain:
days: 7
mode: active_objects
export:
timelapse_args: -vf setpts=PTS/1440 -r 20 -vcodec libx264 -crf 28 -preset slower # PTS/10 = 10x speed. 1440 = 24 hours of video into 1 minute
snapshots:
enabled: true
clean_copy: false
timestamp: true
bounding_box: true
crop: false
quality: 100 # JPEG quality
required_zones: [CarInBikeLane, Pigeon_Watch]
retain:
default: 7 # Retain snapshots for x days
go2rtc:
log:
exec: trace
streams:
bikelane:
ffmpeg:rtsp:xxxxxxxx#video=h264#raw=-vf crop=565:749:230:260 -r 4 -c:v libx264 -preset ultrafast -crf 32 -an
cameras:
bikelane:
enabled: true
ffmpeg:
inputs:
- path: rtsp://xxxxx/bikelane
input_args: preset-rtsp-restream
roles:
- detect
- record
motion:
enabled: true
mask:
0,0,0,1,0.586,1,0.581,0.934,0.554,0.851,0.362,0.864,0.214,0.542,0.136,0.353,0.45,0.354,0.589,0.603,0.696,0.758,0.534,0.767,0.59,0.924,0.595,1,0.8,0.997,1,1,1,0
threshold: 32
contour_area: 5
improve_contrast: false
zones:
CarInBikeLane:
coordinates: 0.463,0.678,0.645,0.673,0.548,0.528,0.391,0.528
inertia: 1
loitering_time: 0
objects: car
CarInCarLane:
coordinates: 0.212,0.575,0.264,0.693,0.46,0.689,0.405,0.576
loitering_time: 0
objects: car
inertia: 1
detect:
enabled: true
min_initialized: 1 # Num of detection hits for an object to be initialized in tracker.
max_disappeared: 4 # Num of frames with no detections before oobject considered gone.
review:
alerts:
labels:
- car
required_zones: CarInBikeLane
detections:
required_zones: CarInBikeLane
objects:
track:
- car # Car detection
- bicycle
filters:
car:
min_area: 3600
max_area: 50000
min_ratio: 0.3
max_ratio: 1.5
min_score: 0.5
threshold: 0.5
mask:
0,0,0,1,1,1,1,0,0,0,0.16,0.36,0.452,0.357,0.683,0.739,0.773,0.823,0.333,0.817,0.147,0.309
record:
enabled: true
retain:
days: 1
detections:
pre_capture: 3
post_capture: 3
retain:
days: 7
mode: active_objects
Watch the Frigate /media/frigate/clips folder for new files and parse the latest eventID into a sensor and build public API endpoints.
Example folder watch sensor output.
event.folder_watcher_media_frigate_clips
Folder Watcher /media/frigate/clips
2025-05-18T10:33:25.390+00:00 event_types: closed, created, deleted, modified, moved
event_type: closed
path: /media/frigate/clips/bikelane-1747564401.500457-kajc9f.jpg
file: bikelane-1747564401.500457-kajc9f.jpg
folder: /media/frigate/clips
friendly_name: Folder Watcher /media/frigate/clips
That sensor is input into this one which builds paths to Frigate api endpoints
- sensor:
- name: "Last car in bikelane eventid"
unique_id: last_car_in_bikelane_eventid
state: "{{ states.event.folder_watcher_media_frigate_clips.attributes.path.split('bikelane-')[1].split('.jpg')[0] }}"
attributes:
full_path_to_clip_image: "{{ states.event.folder_watcher_media_frigate_clips.attributes.path }}"
file_name: "{{ states.event.folder_watcher_media_frigate_clips.attributes.file }}"
api_path_to_event_preview: https://xxx.ui.nabu.casa/api/frigate/notifications/{{ this.state }}/event_preview.gif
api_path_to_event_snapshot: https://xxx.ui.nabu.casa/api/frigate/notifications/{{ this.state }}/snapshot.jpg
api_path_to_event_clip: https://xxx.ui.nabu.casa/api/frigate/notifications/{{ this.state }}/clip.mp4
Example sensor outputs (attributes).
full_path_to_clip_image: /media/frigate/clips/bikelane-1747564401.500457-kajc9f.jpg
file_name: bikelane-1747564401.500457-kajc9f.jpg
api_path_to_event_preview: >-
https://xxc.ui.nabu.casa/api/frigate/notifications/1747564401.500457-kajc9f/event_preview.gif
api_path_to_event_snapshot: >-
https://xxx.ui.nabu.casa/api/frigate/notifications/1747564401.500457-kajc9f/snapshot.jpg
api_path_to_event_clip: >-
https://xxx.ui.nabu.casa/api/frigate/notifications/1747564401.500457-kajc9f/clip.mp4
friendly_name: Last car in bikelane eventid
Notification API
Write some shell commands to move / create files in www
shell_command:
make_bikelane_gif: 'ffmpeg -framerate 4 -pattern_type glob -i "/media/frigate/clips/bikelane*.jpg" -c:v libx264 -crf 30 -r 10 -y /config/www/timelapses/bikelane/bikelane_bboxs.mp4'
copy_latest_bikelane: cp "{{ file_path }}" /config/www/timelapses/bikelane/bikelane_bbox_latest.jpg
Build a dashboard:
type: sections
max_columns: 4
title: Bike Lane
path: bike-lane
sections:
- type: grid
cards:
- type: custom:apexcharts-card
apex_config:
chart:
height: 250px
tickAmount: 5
forceNiceScale: true
graph_span: 24h
header:
show: true
title: Cars in Bike Lane by Hour | Last 24hrs
yaxis:
- apex_config:
tickAmount: 6
series:
- entity: sensor.carinbikelane_car_count
name: Cars in Bike Lane
type: column
color: "#b84b4b"
group_by:
duration: 60min
func: sum
- type: markdown
content: Latest
text_only: true
- type: custom:config-template-card
entities: sensor.last_car_in_bikelane_eventid
card:
type: picture
image: >-
${states['sensor.last_car_in_bikelane_eventid'].attributes['api_path_to_event_preview']}
tap_action:
action: url
url_path: >-
${states['sensor.last_car_in_bikelane_eventid'].attributes['api_path_to_event_clip']}
- type: horizontal-stack
cards: []
- type: grid
cards:
- type: custom:apexcharts-card
apex_config:
chart:
height: 250px
zoom:
enabled: false
xaxis:
labels:
format: ddd dd
graph_span: 7d
header:
show: true
title: Cars in Bike Lane by Day | Last 7 Days
yaxis:
- apex_config:
tickAmount: 4
forceNiceScale: true
series:
- entity: sensor.carinbikelane_car_count
name: Cars in Bike Lane
type: column
color: "#b84b4b"
show:
datalabels: true
group_by:
duration: 24h
func: sum
- type: markdown
content: Latest
text_only: true
- type: custom:config-template-card
entities: sensor.last_car_in_bikelane_eventid
card:
type: picture
image: >-
${states['sensor.last_car_in_bikelane_eventid'].attributes['api_path_to_event_snapshot']}
tap_action:
action: url
url_path: >-
${states['sensor.last_car_in_bikelane_eventid'].attributes['api_path_to_event_clip']}
- type: grid
cards:
- type: custom:apexcharts-card
apex_config:
chart:
stacked: true
stackType: 100%
height: 250px
xaxis:
labels:
format: ddd dd
show:
data_labels: true
graph_span: 7d
header:
show: true
title: Non-compliance by Day | Last 7days
series:
- entity: sensor.bikelane_car_count
name: Bike Lane Count
type: column
color: "#6b6767"
group_by:
duration: 24h
func: sum
- entity: sensor.carinbikelane_car_count
name: Car In Bike Lane
type: column
color: "#b84b4b"
show:
datalabels: true
group_by:
duration: 24h
func: sum
- type: markdown
content: Last 7 Days
text_only: true
- type: horizontal-stack
cards:
- type: iframe
url: /local/timelapses/bikelane/bikelane_bboxs.html
aspect_ratio: 130%
- type: grid
cards:
- type: custom:apexcharts-card
apex_config:
chart:
stacked: true
stackType: 100%
height: 250px
xaxis:
labels:
format: ddd dd
show:
data_labels: true
graph_span: 12w
header:
show: true
title: Non-compliance by week | Last 12w
series:
- entity: sensor.bikelane_car_count
name: Bike Lane Count
type: column
color: "#6b6767"
group_by:
duration: 1w
func: sum
- entity: sensor.carinbikelane_car_count
name: Car In Bike Lane
type: column
color: "#b84b4b"
show:
datalabels: true
group_by:
duration: 1w
func: sum
- type: markdown
content: Latest (All Cars)
text_only: true
- show_state: true
show_name: true
camera_view: auto
fit_mode: cover
type: picture-entity
entity: image.bikelane_car
name: Latest Car (all cars)
- type: logbook
target:
entity_id:
- binary_sensor.carinbikelane_car_occupancy
hours_to_show: 1
icon: mdi:bike
cards: []