This guide explains how to configure dynamic activity calculation for the whereabouts card.
The activity calculation feature allows you to define custom activity strings based on multiple sensor inputs, time context, and conditions. The default display format is:
{name} {verb} {preposition} {location}
For example: "John is at Home"
Activities are optional enhancements displayed on top of this base format.
Instead of hard-coded sensor types, you define custom sensor names that you can reference in activity rules:
namedSensors:
myActivitySensor: # Custom name you choose
entity_id: sensor.john_activity # Single entity
charging: # Another custom name
entity_id: binary_sensor.john_charging
type: status # Optional category for organization
gaming: # Example with multiple entities (OR logic)
entity_id:
- sensor.john_steam
- sensor.john_discord
type: entertainmentKey Points:
- Sensor names are completely custom (you choose them)
- Use
entity_idfor single sensor or array for multiple (OR logic) - Optional
typefield for categorizing sensors - Reference these names in activity rule conditions
type: custom:whereabouts-card
persons:
- entity_id: person.ivar
name: Ivar # Optional custom display name
showActivity: true # Enable activity calculation
# Define custom sensors with names you choose
namedSensors:
activity: # Name used in conditions below
entity_id: sensor.ivar_detected_activity
type: motion
charging:
entity_id: binary_sensor.ivar_is_charging
type: status
sleepConfidence:
entity_id: sensor.ivar_sleep_confidence
type: health
gaming: # Multiple entities = OR logic
entity_id:
- sensor.ivar_steam
- sensor.ivar_discord
type: entertainment
homeOffice:
entity_id: timer.ivar_hjemmekontor
# Activity rules evaluated by priority (highest first)
activityRules:
- id: sleeping
priority: 100
conditions:
- sensor: sleepConfidence # References namedSensors key
operator: gt
value: 90
- personState: home # Person entity state
- timeOfDay: night # Time context
output:
text:
- "Sover hjemme" # Random selection from array
- "Hviler godt"
- "Drømmer søtt"
icon: mdi:power-sleep
- id: gaming
priority: 80
conditions:
- sensor: gaming # Matches if ANY gaming sensor is "playing"
state: playing
output:
text: "Spiller"
icon: mdi:desktop-classic
- id: cycling_to_school
priority: 70
conditions:
- sensor: activity
state: on_bicycle
- dayType: schoolday
- timeOfDay: morning
output:
text: "Sykler til skolen"
icon: mdi:bike
- id: charging_at_home
priority: 60
conditions:
- sensor: charging
state: "on"
- personState: home
output:
text: "Lader telefonen"
icon: mdi:battery-charging
# Fallback when no rules match
fallbackActivity: "Oppholder seg"
fallbackIcon: "mdi:account"
# Card-level settings (optional)
show_title: true
title: Whereabouts
default_verb: is
default_preposition: in
# Zone groups (optional)
zone_groups:
- name: work
zones:
- zone.office
preposition: atReference your custom named sensors:
- sensor: myCustomSensorName # Your custom name from namedSensors
state: expected_value # Expected state (supports arrays for OR)
operator: eq # Optional: eq, ne, gt, lt, gte, lte, contains
value: 90 # Value to compare (for numeric operators)
attribute: nested.path # Optional: check nested attribute instead of stateOperators:
eq(default): Equals - supports arrays for OR logicne: Not equalsgt,lt,gte,lte: Numeric comparisonscontains: String contains (case-insensitive)
Examples:
# Simple state check
- sensor: activity
state: walking
# Multiple acceptable values (OR logic)
- sensor: activity
state: [walking, running, cycling]
# Numeric comparison
- sensor: sleepConfidence
operator: gt
value: 90
# Nested attribute
- sensor: gaming
attribute: game
value: Counter-Strike
# String contains
- sensor: message
operator: contains
value: "hello"# Time of day
- timeOfDay: morning # morning, afternoon, evening, night
# Day type
- dayType: schoolday # weekday, weekend, schooldayTime Ranges:
- Morning: 5:00 - 11:59
- Afternoon: 12:00 - 16:59
- Evening: 17:00 - 21:59
- Night: 22:00 - 4:59
# Single state
- personState: home
# Multiple states (OR logic)
- personState: [home, work, school]Rules are evaluated from highest to lowest priority. The first matching rule wins.
Recommended priority ranges:
- 100-90: Critical states (sleeping, emergency)
- 89-70: Important activities (working, gaming, exercising)
- 69-50: Normal activities (charging, eating)
- 49-30: Movement (walking, cycling, driving)
- 29-10: Generic/fallback rules
Support randomized text for variety:
output:
text: "Single option"
# OR
text:
- "Option 1"
- "Option 2"
- "Option 3"Icons can also be randomized:
output:
icon: mdi:sleep
# OR
icon:
- mdi:sleep
- mdi:power-sleep
- mdi:bedWhen a sensor has multiple entity IDs, any match triggers the condition:
namedSensors:
gaming:
entity_id:
- sensor.steam
- sensor.discord
activityRules:
- conditions:
- sensor: gaming # Matches if Steam OR Discord is "playing"
state: playingTemporarily disable a rule without deleting it:
activityRules:
- id: disabled_rule
enabled: false # Rule will be skipped
conditions: [...]
output: [...]// Node-RED
msg.payload from sensor.detected_activity
// Whereabouts Card
namedSensors:
activity:
entity_id: sensor.detected_activity// Node-RED switch node
if sleep_confidence > 90 AND location == home
// Whereabouts Card
conditions:
- sensor: sleepConfidence
operator: gt
value: 90
- personState: home// Node-RED random node with multiple outputs
// Whereabouts Card
output:
text:
- "Variant 1"
- "Variant 2"
- "Variant 3"The card editor provides an interface for managing configuration:
-
Persons Section (top, primary)
- Add/remove persons
- Configure custom name
- Named Sensors: Add custom sensors with your own names
- Legacy sensors (for backward compatibility)
-
Card Settings (optional, collapsible)
- Title, verb, preposition settings
-
Zone Groups (optional, collapsible)
- Custom zone groupings and prepositions
- Expand the person's "Named Sensors" section
- Enter a custom sensor name (e.g., "activity", "charging", "myCustomSensor")
- Click "Add Sensor" or press Enter
- Provide the entity ID(s) when prompted
- Optionally provide a type/category
- Use descriptive sensor names: Choose names that make sense for your use case
- Start with high priorities: Most important conditions first
- Test time conditions: Verify morning/afternoon/night ranges match your needs
- Use fallback: Always provide a fallback activity
- Group related sensors: Use the optional
typefield to organize sensors - Avoid overlapping rules: Ensure priority order handles overlaps correctly
The matchedRuleId is included in calculated activities (visible in developer tools):
{
text: "Sleeping",
icon: "mdi:power-sleep",
matchedRuleId: "sleeping" // Which rule matched
}- Rule never matches: Check condition sensor names match
namedSensorskeys - Wrong rule matches: Verify priority order
- Time conditions fail: Test at different times of day
- Sensor not updating: Verify entity IDs in Home Assistant