Skip to content

Generic adapter: manual entity mapping for DIY / non-Harvia saunas #25

Description

@krissen

Motivation

The card currently only works with the ha-harvia-sauna integration: entity discovery is locked to the harvia_sauna platform and resolves entities by (domain, translation_key). Users running a DIY sauna (e.g. a homemade KNX controller surfaced through HA's climate entity plus assorted switch/sensor entities) have no such platform, so the card finds no device.

The rendering and control layers are already integration-agnostic: the card renders from a normalized SaunaState and hides anything absent; temperature and switch controls use plain climate.set_temperature / switch.toggle. The missing piece is an adapter that lets the user point the card at their own raw entities.

Proposal

Add a generic adapter (integration: "manual") driven by a user-supplied entity_map (logical key → entity_id), configured in the visual editor as an expandable list of every mappable type, all unchecked by default. Checking a type enables an entity field where the user picks an entity or types an entity_id. No integration required.

The set of mappable types is the same catalog the Harvia adapter already understands (temperature, target temperature, humidity, power, light, fan, steamer, door, heating, power/energy, ...), so a mapped sauna renders identically to the Harvia screenshots, for whatever entities the user has.

Editor UX

When custom mapping is selected, an expandable list of all mappable types appears, everything off by default. Checking a type enables a pick-or-type entity field (ha-entity-picker with custom-entity allowed), filtered to the type's domain. Unchecking removes the key from entity_map.

Design sketch

  • Refactor the body of the Harvia adapter's readState into a shared buildSaunaState(hass, integration, deviceId, entities) so manual mapping and Harvia produce identical state. The Harvia adapter resolves entities via its platform; the manual adapter resolves them from entity_map.
  • A shared catalog (key → { domain, labelKey }) is the single source of truth for editor checkboxes, entity_map, and the state builder.
  • The climate entity is the status/temperature anchor (current_temperature / temperature attributes, hvac_action), with separate sensors as optional overrides.
  • The manual adapter is selectable explicitly (not auto-detected) and never appears in card suggestions.

Acceptance criteria

  • integration: "manual" selectable in the editor; reveals the checkbox-gated entity-map list (all off by default).
  • Checking a type enables a pick-or-type entity field filtered to its domain.
  • A mapped climate (or current/target sensors) renders status + temps and can set temperature.
  • Mapping a switch (e.g. light) shows a working control chip.
  • Unmapped types render nothing (no errors, no empty rows).
  • Works in both card and badge.
  • Contract test with a synthetic DIY fixture (climate + a couple of switches).
  • Docs: a short editor + YAML example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions