Documentation
Complete configuration reference for Chronicle Card.
Installation
HACS (Recommended)
Chronicle Card is in the HACS default store. One-click open:
- Open HACS in your Home Assistant instance
- Search for Chronicle Card and click Download
- Go to Settings → Dashboards → Resources, click Add, and enter
/hacsfiles/chronicle-card/chronicle-card.jsas JavaScript Module - Restart Home Assistant
Manual Installation
- Download
chronicle-card.jsfrom the latest release - Copy to
/config/www/chronicle-card.js - Add the resource in Settings → Dashboards → Resources:
URL:/local/chronicle-card.js, Type: JavaScript Module
Quick Start
Add a new card to any dashboard and paste the following minimal configuration:
Card Options
Top-level configuration options for the card.
| Option | Type | Default | Description |
|---|---|---|---|
type | string | Required | Must be custom:chronicle-card |
title | string | "" | Card title displayed in the header |
layout | string | vertical | vertical or horizontal |
show_layout_toggle | boolean | true | Show button to switch layouts |
max_events | number | 50 | Maximum events to display |
days_back | number | 7 | How many days of history to fetch |
time_format | string | 24h | 12h or 24h |
language | string | auto | Override language (en, de, fr, es, it, pt, nl, sv) |
show_header | boolean | true | Show the card header |
sources | list | Required | Array of source configurations |
filters | object | {} | Filter configuration |
grouping | object | {} | Grouping configuration |
appearance | object | {} | Appearance configuration |
Sources
Chronicle supports four source types. Each source feeds events into the unified timeline. You can combine any number and type of sources in a single card.
Calendar Source
Reads events from a Home Assistant calendar entity.
| Option | Type | Description |
|---|---|---|
entity | string | Calendar entity ID |
REST / WebSocket Source
Fetches events from a REST API endpoint or via Home Assistant WebSocket messages. Use field_map to map response fields to Chronicle's event schema.
REST Example
WebSocket Example (Frigate)
| Option | Type | Description |
|---|---|---|
url | string | REST API endpoint URL |
ws_params | object | WebSocket message parameters (alternative to url) |
response_path | string | Dot-notation path to the events array in the response |
field_map | object | Maps response fields to Chronicle event fields |
media_url_template | string | Template for media URLs with {field} placeholders |
poll_interval | number | Polling interval in seconds |
Field Map Keys
| Key | Description |
|---|---|
id | Unique event identifier |
title | Event title / summary |
description | Event description |
start | Start time (ISO string or Unix timestamp) |
end | End time |
mediaUrl | Direct URL to media (image/thumbnail) |
mediaContentId | HA media content ID |
icon | MDI icon override |
color | Color override |
category | Event category for grouping / filtering |
label | Display label |
severity | Severity level |
entityId | Associated entity ID |
entityName | Associated entity name |
History Source
Converts entity state changes into timeline events. A single history source can watch multiple entities via the entities list, with per-entity overrides via entity_config. Chronicle reads the device_class attribute for smart human-readable translations, and automatically deduplicates repeated words in titles and descriptions (e.g. “Doorbell Motion Motion Cleared” becomes “Doorbell Motion Cleared”). You can attach Jinja2 templates for dynamic thumbnails and HA-native tap/hold actions to each event.
Custom State Map
Override the default state translations with a custom state_map:
State Filter
Use state_filter to only create events when the new state matches one of the listed values. For example, to log only when a motion sensor turns on (ignoring the “off” / cleared transition):
Device Class Translations
The following device classes are automatically translated when no state_map is provided:
| Device Class | On State | Off State |
|---|---|---|
| door / opening / window | Opened | Closed |
| motion | Motion Detected | Motion Cleared |
| lock | Unlocked | Locked |
| smoke | Smoke Detected | Clear |
| moisture | Wet | Dry |
| occupancy | Occupied | Unoccupied |
| presence | Present | Away |
| vibration | Vibration | Still |
| connectivity | Connected | Disconnected |
| battery | Low | Normal |
History Source Options
| Option | Type | Description |
|---|---|---|
entities | string[] | Entity IDs to track state changes for (recommended) |
entity | string | Single entity ID (shorthand — use entities for multiple) |
state_filter | string[] | Source-level default: only log events when the new state matches one of these values |
state_map | object | Source-level default: map of state values to custom display strings |
entity_config | object | Per-entity overrides, keyed by entity ID (see table below) |
image_template | string | Jinja2 template rendered per event to produce a thumbnail URL. Variables: entity_id, state, old_state, timestamp, attributes, source_name |
tap_action | object | Action on tap: more-info, navigate, call-service, or none |
hold_action | object | Action on hold (500ms): same format as tap_action |
Per-Entity Config (entity_config.<entity_id>)
Customize filtering, naming, and appearance for individual entities within a history source. Per-entity settings override source-level defaults, which override auto-detected device class defaults.
| Option | Type | Description |
|---|---|---|
name | string | Custom display name (overrides the entity’s friendly name) |
state_filter | string[] | Only log events matching these states (overrides source-level filter) |
state_map | object | Override state labels for this entity (overrides source-level map) |
icon | string | MDI icon override (e.g. mdi:lock-alert) |
color | string | Hex color override (e.g. #FF9800) |
severity | string | Severity override: critical, warning, info, or debug |
image_template | string | Per-entity image template override (overrides source-level) |
tap_action | object | Per-entity tap action override |
hold_action | object | Per-entity hold action override |
Static Source
Define events directly in YAML. Useful for reminders, scheduled tasks, or manually curated events.
Source Options (All Types)
These options are available on every source type.
| Option | Type | Description |
|---|---|---|
type | string | Source type: calendar, rest, history, or static |
name | string | Display name for the source |
default_icon | string | Fallback MDI icon for events from this source |
default_color | string | Fallback color for events from this source |
default_severity | string | Fallback severity level (critical, warning, info, debug) |
icon_map | object | Map of category/keyword to MDI icon |
color_map | object | Map of category/keyword to color |
actions | list | Action buttons for events from this source |
Filters
Filter events by category, severity, source, entity, or free-text search. Inclusion filters narrow the timeline to only matching events; exclusion filters hide specific items while keeping everything else visible. The visual editor exposes these as a dedicated Filters section with a search field, comma-separated categories input, severity checkboxes (critical, warning, info, debug), source/entity dropdowns, and a nested Exclusions section mirroring the same options.
| Option | Type | Description |
|---|---|---|
categories | list | Only show events matching these categories |
severities | list | Only show events matching these severity levels |
sources | list | Only show events from these source names |
entities | list | Only show events from these entity IDs |
search | string | Free-text search across event titles and descriptions |
exclude_categories | list | Hide events matching any of these categories |
exclude_severities | list | Hide events at any of these severity levels |
exclude_sources | list | Hide events from these source names |
exclude_entities | list | Hide events from these entity IDs |
exclude_search | string | Hide events whose title, description, category, or label contain this string (case-insensitive) |
Grouping
Group nearby events together to reduce visual clutter. The grouping window uses a sliding comparison — each event is compared to the previous event in the group rather than the first, which produces more natural chaining of related events. Group summaries are context-aware: when all grouped events share the same label the summary uses that label (e.g. “7 cat events”), and when events are mixed it falls back to the source or entity name (e.g. “7 Frigate events”).
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable event grouping |
window_seconds | number | 120 | Sliding time window (in seconds) — each event is compared to the previous event in the group |
min_group_size | number | 3 | Minimum number of events to form a group |
group_by | string | category | category, source, entity, or none |
group_name | string | auto | Custom summary label. Supports {count}, {label}, {source}, {entity} placeholders. Falls back to the auto-generated “N X events” summary when unset. |
Per-source grouping override
Each source entry can declare its own grouping block. When set, that source's events are grouped in isolation (events from other sources won't mix into the same group), then merged back into the global timeline by timestamp. Sources without an override fall through to the card-level grouping config above, so existing setups are unchanged.
The visual editor exposes this as a Grouping Override expansion panel inside each source row. Leave any field blank to inherit the card-level value; the Clear override button removes the entire override.
Appearance
Fine-tune the visual style of the card.
| Option | Type | Default | Description |
|---|---|---|---|
card_height | string | 400px | Card body height. A fixed value (e.g. 400px) caps the inner scroll area; fill (or 100%) stretches the card to the full height the dashboard provides — ideal for Panel layout; auto grows with content with no limit. In horizontal mode a fixed value sets the card-strip height and centers the cards within it. |
compact | boolean | false | Use compact event rows |
show_images | boolean | true | Show event thumbnails |
show_icons | boolean | true | Show event icons |
show_severity_badge | boolean | true | Show severity labels on events |
show_source_badge | boolean | false | Show source name badge on events |
show_category | boolean | true | Show the category / label / entity-name pill row beneath each event title. Disable for a denser layout that keeps icons and descriptions but drops the metadata pills. |
animate_new_events | boolean | true | Animate new events as they arrive |
severity_colors | object | (built-in) | Override severity level colors |
Actions
Add action buttons to events. Actions can navigate, call services, or fire custom events.
| Option | Type | Description |
|---|---|---|
label | string | Button label text |
icon | string | MDI icon for the button |
type | string | Action type: service, navigate, or fire-event |
service | string | Service to call (for service type) |
serviceData | object | Additional data for the service call |
target | object | Target entity/device/area for the service call |
url | string | URL to navigate to (for navigate type) |
eventType | string | Custom event type (for fire-event type) |
eventData | object | Data payload for the custom event |
Icon & Color Resolution
Chronicle resolves icons and colors through a 5-level chain. The first match wins.
color_map/icon_map— custom per-source overridesdefault_color/default_icon— per-source fallback values- Fuzzy keyword inference — 150+ built-in rules that match event titles and categories
- Category defaults — built-in icons for common categories
- Global fallback —
mdi:calendar-clock/#78909C
Keyword Match Examples
| Keywords | Icon | Color |
|---|---|---|
| cat, kitten, feline | mdi:cat | #7f41eb |
| dog, puppy, canine | mdi:dog | #8D6E63 |
| person, visitor | mdi:walk | #FF9800 |
| car, truck, vehicle | mdi:car | #2196F3 |
| package, delivery | mdi:package-variant-closed | #795548 |
| alarm, alert | mdi:alarm-light | #F44336 |
| door, gate | mdi:door | #795548 |
| motion | mdi:motion-sensor | #9C27B0 |
| camera, cctv | mdi:cctv | #FF5722 |
| light, lamp | mdi:lightbulb | #FFC107 |
| temperature | mdi:thermostat | #00BCD4 |
Override Example
Severity System
Chronicle supports four severity levels. Each event can have a severity set via the source default_severity, field_map, or static event config. Severity badges appear on events and can be restyled via appearance.severity_colors.
| Level | Default Color | Use Case |
|---|---|---|
| Critical | #D32F2F | Alarm triggers, smoke detection, security breaches |
| Warning | #FF9800 | Person detected, door opened, unusual activity |
| Info | #2196F3 | Calendar events, routine activity, status changes |
| Debug | #9E9E9E | Low-priority logs, diagnostic data |
Layouts
Chronicle provides two layout modes:
- Vertical (default) — A scrollable timeline with a timeline line and event nodes. Best for detailed event inspection.
- Horizontal — A ribbon layout for compact display (e.g., camera events as a horizontal strip). Best for dashboards with limited vertical space.
Toggle between them at runtime with show_layout_toggle: true, or set a fixed layout:
Log Event Blueprint
A ready-to-use Home Assistant automation blueprint is included at blueprints/chronicle_log_event.yaml. It logs entity state changes to a calendar entity, which Chronicle then reads as timeline events.
Blueprint Inputs
| Input | Description |
|---|---|
| Trigger Entity | The entity to watch for state changes |
| Trigger State (optional) | Only log when entity enters this specific state |
| Target Calendar | Calendar entity where events are written |
| Event Title | Template-supported title (default: friendly name + state) |
| Event Description | Template-supported description body |
| Event Duration | Duration in minutes |
| Additional Condition | Optional extra condition to gate logging |
Usage Example
Camera Detection Snapshots Blueprint
For cameras that expose AI detections as binary sensors (Reolink, Amcrest, ONVIF, etc.), this blueprint captures a snapshot on each detection and saves it with a timestamp-based filename. Chronicle Card's image_template then matches each timeline event to its snapshot automatically.
Prerequisites
- Input Number Helper — Create via Settings → Devices & Services → Helpers → Add Helper → Number. Name it
chronicle_snapshot_retention, min 1, max 30, step 1, initial 7, unit "days". Alternatively, add toconfiguration.yaml:input_number: chronicle_snapshot_retention: name: Chronicle Snapshot Retention icon: mdi:calendar-clock min: 1 max: 30 step: 1 initial: 7 unit_of_measurement: days - Shell Command — Add to
configuration.yaml:shell_command: clean_chronicle_snapshots: "find /config/www/snapshots -type f -name '*_????????_??????.jpg' -mtime +{{ states('input_number.chronicle_snapshot_retention') | int(7) }} -delete" - Snapshot directory — Create
/config/www/snapshots/if it doesn't exist.
Card Configuration
Add image_template to your history sources to match events to their snapshots:
Both the blueprint and image_template normalize through as_timestamp (epoch seconds) then timestamp_custom (HA's local timezone), ensuring filenames match regardless of timezone configuration.
Supported Cameras
- Reolink — person, vehicle, pet, face, package, visitor (doorbell)
- Amcrest / Dahua — motion, person, vehicle
- Generic ONVIF — motion, person (if supported by firmware)
- Any camera with binary_sensor detection entities + a camera entity for snapshots
Does not replace Frigate — Frigate has its own event system with built-in thumbnails. Use the REST adapter with media_url_template for Frigate instead.
days_back on your Chronicle Card to match the blueprint's retention days so snapshots exist for all visible events.
Example: LLM Vision Integration
Pair the LLM Vision integration with image_template so each timeline event can show its analyzed snapshot. The automation saves the frame to a predictable path (timestamp-based) and the card's template matches each event to its snapshot.
1. Save the snapshot in your automation
2. Match the snapshot in Chronicle
Use the same timestamp format in image_template so each event resolves to its own saved frame:
The LLM caption ends up in input_text.doorbell_last_caption and can be surfaced via a separate static or REST source if you want it on the timeline alongside the snapshot. The Camera Snapshots blueprint above can replace step 1 entirely if you only need the snapshot without analysis.
Example: Frigate Camera Events
Display Frigate NVR detections with snapshot thumbnails in a timeline.
Example: Multi-Source Home Timeline
Combine calendar events, camera detections, and door sensor history in one view.
Example: Compact Security Log
A compact, filtered view showing only security-relevant events.
Example: Horizontal Camera Ribbon
Show Frigate events as a horizontal scrolling ribbon with thumbnails.
Example: Logging Automations
Use Home Assistant automations to write events into a calendar entity that Chronicle reads. This approach lets you log any state change, webhook, or trigger as a timeline event.
Localization
Chronicle auto-detects the language from your Home Assistant locale. Override it with the language card option.
| Code | Language |
|---|---|
en | English |
de | German |
fr | French |
es | Spanish |
it | Italian |
pt | Portuguese |
nl | Dutch |
sv | Swedish |
Development
To build and develop Chronicle Card locally:
Output is written to dist/chronicle-card.js. Copy it to your Home Assistant /config/www/ directory during development.