fix: keep manual virtual light face canonical

Issue: #107
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-08-14 03:55:06 +03:00
parent f1e6cca3db
commit de0171dd02
8 changed files with 144 additions and 91 deletions
+10 -3
View File
@@ -24,6 +24,7 @@ import type { DevItem } from './types';
import { safeStoredColor } from './color';
import { resolveDeviceValueBadge, type ResolvedValueBadge } from './device-value-badge';
import { resolveDevicePulse, type ResolvedDevicePulse } from './device-pulse';
import { isManualVirtualLightMarker } from './virtual-light-state';
export type PresentationSourceKind =
| 'cover' | 'light' | 'controls' | 'device_role' | 'primary' | 'none';
@@ -248,9 +249,14 @@ export function resolvePresentationSources(
source.device.id === d.id && source.via !== 'controls'
);
const localOwned = localLights.filter((source) => source.via !== 'controls');
const lights = [
const ownedLights = globalOwned.length ? globalOwned : localOwned;
// In #107's exact manual mode, outgoing controls remain saved and active in
// the plan graph, but they do not own this marker's face. Its icon/status is
// the same canonical manual source used by Glow, room fill and statistics.
const manualVirtualFace = isManualVirtualLightMarker(d.marker);
const lights = manualVirtualFace ? [...ownedLights] : [
...localLights.filter((source) => source.via === 'controls'),
...(globalOwned.length ? globalOwned : localOwned),
...ownedLights,
];
if (markerRefs.size) {
for (const source of globalLights) {
@@ -277,7 +283,8 @@ export function resolvePresentationSources(
sourceKind = 'cover';
visualSources = [sourceOf(hass, cover, 'cover')];
} else if (lights.length) {
sourceKind = lights.some((source) => source.via === 'controls') ? 'controls' : 'light';
sourceKind = !manualVirtualFace && lights.some((source) => source.via === 'controls')
? 'controls' : 'light';
visualSources = lights.map((source) => {
const role = source.via === 'controls' ? 'control'
: source.via === 'forced' ? 'forced_light' : 'light';
+2 -2
View File
@@ -357,7 +357,7 @@ class HouseplanSpaceCard extends LitElement {
.map(([id, runtime]) => `${id}:${runtime.gen}:${runtime.flashTs}:`
+ `${runtime.flashKind && (runtime.expiresAt || runtime.flashTs + 3300) > now ? 1 : 0}`)
.join('|');
const virtualFingerprint = this._snap
const virtualFingerprint = this._snap?.virtualLights
? `${this._snap.virtualLights.configRev}:${this._snap.virtualLights.rev}` : '';
if (this._capturedSnapshotSequence === this._hassSequence
&& this._capturedSnapshotDevices === this._devices
@@ -463,7 +463,7 @@ class HouseplanSpaceCard extends LitElement {
snap?.configFingerprint || contentFingerprint(snap?.config),
snap?.layoutRev || 0,
snap?.layoutFingerprint || contentFingerprint(snap?.layout),
snap ? `${snap.virtualLights.configRev}:${snap.virtualLights.rev}` : '',
snap?.virtualLights ? `${snap.virtualLights.configRev}:${snap.virtualLights.rev}` : '',
this._config?.space || '',
this._stageWidth,
this.hass?.themes?.darkMode ?? this.hass?.themes?.default_theme ?? '',