mirror of
https://github.com/Matysh/houseplan-card
synced 2026-08-01 00:48:29 +00:00
Agreed with the owner: whether a device is on the plan is a CHECKBOX
('Hide device from plan', every kind incl. virtual), not a runtime
algorithm. The old filter survives only as the SEEDER of those flags.
- marker.hidden is the flag; hidden devices are BUILT (room LQI counts
them — owner's decision) but rendered only in the device editor with
'Show hidden' on, ghosted. They cast no glow and no light fill: an
invisible device casts no visible light (owner's decision).
- seedHiddenBindings(): non-physical devices (excluded domains, Group,
scene, bridge, myheat children, grouped lamps) in bound areas WITHOUT a
marker. The editing client materialises them into hidden:true stub
markers, sets settings.filter_seeded, retires settings.show_all, and
strips fresh-hidden ids from the red-dot list. Unticking the checkbox
keeps a hidden:false marker — the seeder never revisits a marked device,
so the user's decision is final. New non-physical devices hide silently;
physical ones keep the red-dot flow.
- legacy configs (no filter_seeded) keep the OLD behaviour verbatim —
runtime filter, shared show_all, hidden-means-gone — until an editing
client materialises them, so a read-only tablet never sees a half-state.
- 'Show all' is renamed 'Show hidden' and is LOCAL to the tab; the shared
settings.show_all retires with the runtime filter.
- 'Remove from plan' disappears for auto/entity devices (the checkbox is
the way); a virtual device's Delete remains a real deletion.
- docs/FILTERING.md is the source of truth for the mechanism.
Tests: seeder/seeded/legacy/lights units (146), smoke_hidden_flag with 12
assertions (68 smokes). Inventory: 146 / 51 / 43 / 68.
139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
/** Shared types of the House Plan card. */
|
|
|
|
export interface RoomCfg {
|
|
/** Rooms this one has an OPEN (virtual) boundary with - light flows through. */
|
|
open_to?: string[] | null;
|
|
/** Room-level settings (tier 3 of 4: global > space > ROOM > device). */
|
|
settings?: {
|
|
/** Fill override; unset = inherit the space fill mode. */
|
|
fill_mode?: 'none' | 'lqi' | 'light' | 'temp' | null;
|
|
/** 'device:<id>' or 'entity:<eid>'; unset = average over the room sensors. */
|
|
temp_source?: string | null;
|
|
hum_source?: string | null;
|
|
/** Font multipliers for THIS room's card (0.5-3, unset = 1). */
|
|
name_scale?: number | null;
|
|
label_scale?: number | null;
|
|
} | null;
|
|
id?: string;
|
|
name: string;
|
|
area: string | null;
|
|
x?: number;
|
|
y?: number;
|
|
w?: number;
|
|
h?: number;
|
|
poly?: number[][]; // polygon in render units (model) / normalized (config)
|
|
}
|
|
|
|
export interface SpaceModel {
|
|
id: string;
|
|
title: string;
|
|
vb: number[]; // render units
|
|
bg: { href: string; x: number; y: number; w: number; h: number } | null;
|
|
rooms: RoomCfg[]; // render units
|
|
}
|
|
|
|
export interface PdfRef {
|
|
name: string;
|
|
url: string;
|
|
}
|
|
|
|
/** Config marker: edits/augments an auto-discovered device OR describes a manual/virtual icon. */
|
|
export interface Marker {
|
|
id: string;
|
|
binding: string; // 'device:<id>' | 'entity:<eid>' | 'virtual'
|
|
space?: string | null;
|
|
area?: string | null;
|
|
hidden?: boolean;
|
|
name?: string | null;
|
|
icon?: string | null;
|
|
model?: string | null;
|
|
link?: string | null;
|
|
description?: string | null;
|
|
pdfs?: PdfRef[];
|
|
tap_action?: string | null; // per-device override: 'info' | 'more-info' | 'toggle'
|
|
room_id?: string | null; // manual placement into a room WITHOUT an HA area (sub-area rooms)
|
|
display?: 'badge' | 'ripple' | 'icon_ripple' | 'value' | null; // how the device is drawn
|
|
ripple_color?: string | null;
|
|
ripple_size?: number | null; // max ring diameter, in icon diameters (default 3)
|
|
size?: number | null; // icon size multiplier (default 1)
|
|
angle?: number | null; // icon rotation, degrees
|
|
/** Entities this icon toggles as a group (wall switch → its lights). */
|
|
controls?: string[] | null;
|
|
/** Per-source glow radius in cm (glow fill); null = the global default. */
|
|
glow_radius_cm?: number | null;
|
|
/**
|
|
* Treat this marker as a light source in the glow fill even when it has no
|
|
* light.* entity (a smart switch driving dumb fixtures — field request).
|
|
* null/undefined = auto: any light.* entity of the device.
|
|
*/
|
|
is_light?: boolean | null;
|
|
}
|
|
|
|
/** A door or window: plan geometry (normalized coords), optionally live via entities. */
|
|
export interface OpeningCfg {
|
|
id: string;
|
|
type: 'door' | 'window';
|
|
x: number; // center, normalized by plan width
|
|
y: number; // center, normalized by plan height
|
|
angle: number; // wall angle, degrees
|
|
length: number; // along the wall, normalized by plan width
|
|
contact?: string | null; // binary_sensor / cover driving open-closed
|
|
lock?: string | null; // lock entity (doors only)
|
|
invert?: boolean;
|
|
flip_h?: boolean; // hinge on the other jamb
|
|
flip_v?: boolean; // opens to the other side of the wall
|
|
}
|
|
|
|
export interface ServerConfig {
|
|
spaces: any[];
|
|
markers: Marker[];
|
|
settings: {
|
|
exclude_integrations?: string[];
|
|
group_lights?: boolean;
|
|
show_all?: boolean; // legacy: removed when the config is materialised
|
|
/** The filter flags are materialised into markers (docs/FILTERING.md). */
|
|
filter_seeded?: boolean;
|
|
icon_rules?: { pattern: string; icon: string }[];
|
|
};
|
|
}
|
|
|
|
export interface DevItem {
|
|
id: string;
|
|
name: string;
|
|
model: string;
|
|
area: string;
|
|
space: string;
|
|
/** "Hide from plan": built (so room LQI still counts it) but not rendered,
|
|
* except ghosted in the device editor with "show hidden" on. */
|
|
hidden?: boolean;
|
|
icon: string;
|
|
entities: string[];
|
|
primary?: string;
|
|
temp?: number | null;
|
|
hum?: number | null;
|
|
virtual?: boolean;
|
|
marker?: Marker; // linked config marker (metadata, overrides)
|
|
bindingKind?: 'device' | 'entity' | 'virtual';
|
|
bindingRef?: string; // device_id / entity_id
|
|
link?: string | null;
|
|
description?: string | null;
|
|
pdfs?: PdfRef[];
|
|
tapAction?: string | null; // from the marker override
|
|
}
|
|
|
|
export interface CardConfig {
|
|
type: string;
|
|
title?: string;
|
|
default_floor?: string;
|
|
icon_size?: number;
|
|
show_temperature?: boolean;
|
|
live_states?: boolean;
|
|
show_signal?: boolean;
|
|
language?: string; // 'en' | 'ru' | '' (auto — HA profile)
|
|
tap_action?: string; // legacy, ignored since v1.38.1
|
|
/** Wall-device (kiosk) mode: no header, no editors, swipe between spaces. */
|
|
kiosk?: boolean;
|
|
/** Kiosk auto-carousel: seconds between space switches, 0/undefined = off. */
|
|
cycle?: number;
|
|
}
|