hrv-card attributes
| Attribute | Required | Description |
entity | Yes* | HA entity ID. e.g. light.bedroom_main. Use either entity or alias. |
alias | Yes* | 8-character random alias as assigned in the panel. Alternative to entity. |
token | No | Widget token ID. Inherits from group or HArvest.config() if not set. |
ha-url | No | HA external HTTPS URL. Inherits from group or HArvest.config() if not set. |
token-secret | No | HMAC signing secret. Required when the token has HMAC enabled. |
hrv-group attributes
| Attribute | Description |
token | Token ID inherited by all child cards |
ha-url | HA URL inherited by all child cards |
token-secret | HMAC secret inherited by all child cards |
JavaScript API
| Method / Property | Description |
HArvest.config(options) | Set page-level defaults. Merges on repeated calls. See PageConfig options. |
HArvest.create(config) | Programmatically create and mount an HrvCard. Returns the element. |
HArvest.getCard(entityId) | Get the HrvCard instance for an entity ID, or null. |
HArvest.registerRenderer(key, Class) | Register a custom renderer for a domain or domain.device_class. Last write wins. |
HArvest.renderers | Object containing all built-in renderer classes for extension. |
HArvest.track.anyState(callback) | Register a callback for all entity state changes on the page. |
HArvest._packs internal | Renderer pack namespace. Used by renderer pack authors to register alternative card renderers. Not part of the public API; may change between versions. |
HArvest.config() options
| Option | Type | Default | Description |
haUrl | string | - | HA external HTTPS URL |
token | string | - | Widget token ID |
tokenSecret | string | - | HMAC signing secret |
colorScheme | "auto" | "light" | "dark" | "auto" | Page-level color scheme fallback. Token server setting takes priority. |
WordPress shortcodes
[harvest]
| Parameter | Required | Description |
token | Yes | Widget token ID |
entity | Yes* | HA entity ID |
alias | Yes* | 8-character entity alias. Use entity or alias, not both. |
token-secret | No | HMAC signing secret |
[harvest_group]
| Parameter | Required | Description |
token | Yes | Shared token ID for all child cards |
token-secret | No | Shared HMAC secret for all child cards |
Token fields
All token settings are configured in the panel. This table describes what each field controls.
| Field | Type | Default | Description |
| Label | string | - | Display name in the panel. Not exposed to visitors. |
| Entities | list | - | List of entity IDs with per-entity capability and settings. |
| Allowed origins | list | - | Websites allowed to connect. Empty = any (if allow_any is set) or rejection. |
| Allow any origin | boolean | false | Skip origin checking entirely. |
| Expires at | ISO datetime | null | null | Token expiry. Null = never expires. |
| Active schedule | object | null | null | Day/hour restriction with IANA timezone. |
| Allowed IPs | CIDR list | - | IP allowlist. Requires trusted_proxies in HA config. |
| Token secret | string | null | null | HMAC signing secret. Null = HMAC disabled. |
| Max sessions | integer | null | null | Max concurrent sessions. Null = unlimited. |
| Session lifetime | minutes | 60 | Session duration before renewal required. |
| Max session lifetime | minutes | 1440 | Maximum total duration via renewals. |
| Theme | theme ID | null | null | Theme assigned to this token. Null = Default theme. |
| Lang | BCP 47 | "auto" | "auto" | Widget language. "auto" follows browser language. |
| A11y | "standard" | "enhanced" | "standard" | Accessibility mode. |
| On offline | string | "last-state" | "dim", "hide", "message", or "last-state". |
| On error | string | "message" | "dim", "hide", or "message". |
| Offline text | string | "" | Custom message shown when entity is offline. |
| Error text | string | "" | Custom message shown on connection error. |
Per-entity settings
Configured per entity within a token from the Entities tab in the widget detail screen.
| Setting | Type | Default | Description |
| Display name | string | null | null | Overrides the entity's HA friendly name in the widget. Null = use HA name. |
| Icon | mdi:<name> | null | null | Overrides the auto-detected icon for all states. Null = use domain default. |
| Force color scheme | "auto" | "light" | "dark" | "auto" | Forces the widget card into light or dark mode regardless of the visitor's OS setting. |
| Capability | "badge" | "read" | "read-write" | "read-write" | "badge" renders a compact pill indicator with no controls, companions, or gestures. "read" is a full card, view only. "read-write" is a full card with control (service calls). |
| Alias | string | null | null | 8-character random alias. Generated in the wizard, or manually in the detail screen. |
| Exclude attributes | string list | - | HA attribute names to strip before sending to widget. Bidirectionally linked with domain-specific display controls. |
| Graph type | "line" | "bar" | null | null | History graph for sensors and input_number. Null = no graph. Stored in display_hints.graph. |
| Graph hours | 1-168 | 24 | Time window for history graph. Stored in display_hints.hours. |
| Graph period | 1-60 | 10 | Aggregation period in minutes per data point. Stored in display_hints.period. |
| Fan display mode | "auto" | "on-off" | "continuous" | "stepped" | "cycle" | "auto" | Controls which fan speed UI is shown. "auto" lets the renderer decide based on the entity's features. Stored in display_hints.display_mode. Only visible when the active theme pack supports it. |
| Animate fan | boolean | false | Spin the fan icon when entity is on. Stored in display_hints.animate. |
| Companions | entity list | - | Companion entities displayed inside this card. Managed in the Entity Settings card; do not appear in the entity list. 50-entity token budget applies. See companion eligibility. |
| Badge: show icon | boolean | true | Show icon in badge pill. Only visible when capability is "badge". Stored in display_hints.badge_show_icon. |
| Badge: show name | boolean | true | Show name in badge pill. Stored in display_hints.badge_show_name. |
| Badge: show state | boolean | true | Show state in badge pill. Stored in display_hints.badge_show_state. |
| Badge: icon color | string | "auto" | Icon color when entity is active. Auto derives from domain. Options: auto, red, orange, amber, yellow, green, teal, cyan, blue, indigo, purple, pink, grey. Stored in display_hints.badge_icon_color. |
| Gesture: tap | action | null | null | Action on single tap: toggle, trigger a Harvest Action, or no action. Not available for badge entities. |
| Gesture: hold | action | null | null | Action on hold. Not available for badge entities. |
| Gesture: double tap | action | null | null | Action on double tap. Not available for badge entities. |
Global settings
Configured in the panel Settings screen. Applies to all tokens unless overridden per-token.
| Setting | Default | Description |
| Override host | (empty) | The public URL the panel uses when generating snippets and computing the HA-served widget script URL. Empty means use the URL of whatever HA host the admin is currently visiting. Set this to your external HA URL when admins access HA via a different domain than visitors will use. |
| Widget script source | HA-served | Two radios: HA-served (default, snippet uses {HA_URL}/harvest_assets/harvest.min.js; always matches the running integration), or Custom URL (admin-supplied). HA-served eliminates widget-vs-server version drift since the bundle ships inside the integration. |
| Auth timeout | 10s | WebSocket auth must complete within this window. |
| Keepalive interval | 30s | Server-to-client ping frequency. |
| Client heartbeat timeout | 60s | Session dropped if no client message within this window. |
| Max entities per token | 50 | Hard cap on entities per token. |
| Auth attempts per token/min | 10 | Failed attempts before token is temporarily blocked. |
| Auth attempts per IP/min | 20 | Failed attempts per IP before blocking. |
| Kill switch | Off | Drops all sessions globally and blocks new connections. |
| Default session lifetime | 60 min | Session duration before renewal required. |
| Max session lifetime | 1440 min | Maximum total duration via renewals. |
| Absolute session cap | 72 hours | Hard session expiry regardless of renewals. |
| Activity log retention | 30 days | How long events are stored before deletion. |
CSS variables (summary)
Full descriptions on the Theming page. All variables are prefixed --hrv-.
| Category | Variables |
| Colors | --hrv-color-primary, --hrv-color-primary-dim, --hrv-color-on-primary, --hrv-color-surface, --hrv-color-surface-alt, --hrv-color-border, --hrv-color-text, --hrv-color-text-secondary, --hrv-color-text-inverse, --hrv-color-icon, --hrv-color-state-on, --hrv-color-state-off, --hrv-color-state-unavailable, --hrv-color-warning, --hrv-color-error, --hrv-color-success, --hrv-color-overlay, --hrv-color-overlay-text |
| Card | --hrv-card-background, --hrv-card-radius, --hrv-card-shadow, --hrv-card-padding |
| Typography | --hrv-font-family, --hrv-font-size-xs, --hrv-font-size-s, --hrv-font-size-m, --hrv-font-size-l, --hrv-font-weight-normal, --hrv-font-weight-medium, --hrv-font-weight-bold |
| Spacing | --hrv-spacing-xs, --hrv-spacing-s, --hrv-spacing-m, --hrv-spacing-l, --hrv-radius-s, --hrv-radius-m, --hrv-radius-l, --hrv-icon-size, --hrv-transition-speed |
Theme JSON schema
{
"name": "string (required)",
"harvest_version": 1,
"variables": {
"--hrv-color-primary": "#hex or any CSS color value",
"...": "..."
},
"dark_variables": {
"--hrv-color-surface": "#hex",
"...": "..."
},
"author": "string (optional)",
"version": "string (optional)",
"renderer_pack": "pack-id | true (optional)"
}
Error codes
All error codes are HRV_-prefixed. They appear in auth failure activity log events, in auth_failed WebSocket messages, and in ack error responses. See SPEC.md Section 6 for the canonical list and per-code retryability notes.
| Code | Meaning |
HRV_TOKEN_INVALID | Token ID not found, or syntactically malformed. Both cases collapse to the same code intentionally so a probing attacker cannot distinguish format errors from missing tokens. |
HRV_TOKEN_EXPIRED | Token has passed its expires date. |
HRV_TOKEN_REVOKED | Token has been manually revoked. |
HRV_TOKEN_INACTIVE | Token is paused, outside its active_schedule window, or the kill switch is active. Retryable with backoff. |
HRV_ORIGIN_DENIED | Origin (or page_path) not in the token's allowed list. |
HRV_IP_DENIED | Client IP not in the token's allowed_ips ranges. |
HRV_SIGNATURE_INVALID | HMAC signature verification failed (bad signature, stale timestamp, or timestamp more than 5 seconds in the future). |
HRV_PROTOCOL_INCOMPATIBLE | The widget speaks a WebSocket protocol version the server cannot accept. Typically a stale cached snippet outliving an integration update. The auth_failed response includes a server block (with protocol, version, and min_client_protocol) so the widget can render a useful diagnostic. Visitors see "Widget version cannot connect to this server. Update your snippet" rather than the generic "Widget unavailable". Permanent; no reconnect. |
HRV_ENTITY_NOT_IN_TOKEN | None of the submitted entity references resolved within the token's scope. Individual unresolvable refs are silently skipped during auth and logged to the activity store with internal code ENTITY_REF_DROPPED; this code is returned only when zero refs resolve. |
HRV_ENTITY_INCOMPATIBLE | Entity domain is on the Tier 3 blocked list. Returned at token creation time; per-ref incompatibility during auth is silently skipped (and logged as ENTITY_REF_DROPPED). |
HRV_SESSION_LIMIT_REACHED | Token's max_sessions or max_renewals limit reached. |
HRV_AUTH_FAILED | Generic auth failure surfaced to the visitor when a more specific code would leak token state. |
HRV_PERMISSION_DENIED | Capability not granted for the requested action, or the service is not in the ALLOWED_SERVICES whitelist. |
HRV_RATE_LIMITED | Rate limit exceeded (per-token or per-IP). The ack includes a retry_after value in seconds. |
HRV_SESSION_EXPIRED | Session lifetime exceeded; client must re-authenticate. |
HRV_ENTITY_MISSING | Entity not found in HA at runtime. |
HRV_ENTITY_REMOVED | Entity was deleted from HA after auth. Permanent for the lifetime of the session. |
HRV_BAD_REQUEST | Malformed message that included a msg_id. The session stays open. |
HRV_MESSAGE_TOO_LARGE | Inbound WebSocket frame exceeded the 4 KB limit. The connection is closed. |
HRV_SERVER_ERROR | Internal HA or integration error. |
The widget defines four additional client-only states that never appear in server activity logs: HRV_OFFLINE (cannot reach the server), HRV_STALE (heartbeat timeout), HRV_CONNECTING (initial handshake in progress), and HRV_INCOMPATIBLE (the widget-side state name set when an auth_failed with HRV_PROTOCOL_INCOMPATIBLE arrives; permanent, no reconnect). These are documented in SPEC.md Section 8.