Skip to content

Rules Engine

window.lcards.core.rulesManager — Evaluates conditions and hot-patches card styles at runtime.


Overview

RulesEngine extends BaseService. It maintains a compiled index of rules, tracks which entities each rule depends on, and re-evaluates dirty rules on every HASS state push. Matched rules produce patches — plain style objects that are merged onto target overlays without those overlays needing to know the rule exists.


Key Classes

ClassFileRole
RulesEnginecore/rules/RulesEngine.jsEvaluation loop, dependency index, patch distribution
compileConditionscore/rules/compileConditions.jsCompiles rule when DSL to optimised predicate functions
RuleTraceBuffercore/rules/RuleTraceBuffer.jsRing buffer of evaluation events for the Debug Panel

Evaluation Flow

HASS state push
    → mark affected rules dirty  (dependency index O(1) lookup)
    → evaluate dirty rules only  (compiled predicates)
    → for each matched rule: compute patches
    → distribute patches to registered overlay listeners
    → overlays call requestUpdate()

Rule Schema

yaml
rules:
  - id: high_temp
    priority: 10             # higher number = evaluated first
    stop: false
    enabled: true
    when:
      entity: sensor.cpu_temp
      above: 75
    apply:
      overlays:
        tag:temp_widget:     # tag selector — all overlays tagged 'temp_widget'
          style:
            color: var(--lcars-red)
      animations:
        - tag: temp_widget
          preset: alert_pulse
          loop: true

  - id: motion_active
    when:
      entity: binary_sensor.front_door
      state: "on"
    apply:
      overlays:
        front-door-button:   # direct overlay ID
          style:
            color: var(--lcars-orange)

Condition Operators

OperatorValue typeMeaning
statestringExact state match (alias for equals)
equalsstring/numberExact equality
not_equalsstring/numberInequality
abovenumbernumeric_state > value (strictly greater)
belownumbernumeric_state < value (strictly less)
inarrayState is one of the listed values
not_inarrayState is not in the listed values
regexstringState matches regular expression
attributestringAttribute name — pair with comparison operator
allcondition[]AND — all nested conditions must match
anycondition[]OR — at least one nested condition must match
notconditionNegate a nested condition
conditionstringJS [[[code]]] or Jinja2 {{template}} — truthy return
jinja2stringExplicit Jinja2 template
javascriptstringExplicit JavaScript expression
time_between"HH:MM-HH:MM"True when current time is in range
weekday_instring[]True when today is one of monsun
sun_elevation{ above?, below? }True when sun elevation matches
perf_metric{ key, above?, below? }Internal performance metric comparison
random_chancenumber 0–1True with given probability each evaluation

Targeting

The keys of apply.overlays are selectors. Each maps to a patch fragment:

Selector formMatches
overlay-idExact overlay ID (direct match)
tag:tagnameAll overlays with tag tagname
type:typenameAll overlays of type typename
pattern:regexAll overlays whose ID matches the regex
allEvery registered overlay
excludeArray of IDs to exclude from bulk selectors

Multiple selectors in one rule are merged; later selectors' style keys override earlier ones for the same overlay.


Card Integration

javascript
// Register overlay (in _handleFirstUpdate)
this._registerOverlayForRules({ id: `btn-${this._cardGuid}`, type: 'button' });

// Receive patches
_onRulePatchesChanged(patches) {
  this._resolveStyle();   // merge config.style + patches, then requestUpdate()
}

Priority & Stop Processing

Higher priority number wins when multiple rules target the same overlay property (default 0). Rules are evaluated in descending priority order.

Set stop: true on a rule to prevent lower-priority rules from running at all once this rule matches.


Public API

Property / MethodReturnsDescription
rulesRule[]All registered rules in evaluation order
rulesByIdMap<id, Rule>Rules keyed by ID for fast lookup
getAllRules()Rule[]Array of all registered rule objects
getTrace()ObjectDetailed evaluation trace with per-overlay match history
getRecentMatches(windowMs)Match[]All rule matches within the last N milliseconds
getRuleTrace(ruleId, limit?)Object[]Per-rule match history with optional result count limit

Console Access

javascript
window.lcards.debug.singleton('rulesManager')
// → { type: 'RulesEngine', rulesCount: 3, dirtyRules: 0, evalCounts: {...}, trace: {...} }
javascript
const rm = window.lcards.core.rulesManager

rm.rules                            // full rules array
rm.rulesById                        // Map<id, rule>
rm.getTrace()                       // detailed evaluation trace
rm.getRecentMatches(30000)          // matches in the last 30s
rm.getRuleTrace('my-rule-id', 20)   // history for one rule
rm.getAllRules()                     // array of all registered rules

See Also