@@ -145,7 +145,7 @@ const applianceSpace = {
|
||||
decor: [],
|
||||
};
|
||||
|
||||
const runtime = () => {
|
||||
const runtime = (includeAppliance = false) => {
|
||||
const devices = {};
|
||||
const entities = {};
|
||||
const states = {
|
||||
@@ -159,7 +159,7 @@ const runtime = () => {
|
||||
// The production projection must preserve them.
|
||||
const layout = {};
|
||||
const areas = Object.fromEntries(
|
||||
[...geometryRooms, ...lightingRooms, ...applianceRooms]
|
||||
[...geometryRooms, ...lightingRooms, ...(includeAppliance ? applianceRooms : [])]
|
||||
.map((room) => [room.area, { area_id: room.area, name: room.name }]),
|
||||
);
|
||||
const add = (id, domain, area, x, y, state, attributes = {}) => {
|
||||
@@ -196,57 +196,59 @@ const runtime = () => {
|
||||
unit_of_measurement: 'lqi',
|
||||
});
|
||||
|
||||
const washerId = 'golden-washer';
|
||||
devices[washerId] = {
|
||||
id: washerId,
|
||||
name: 'Golden washing machine',
|
||||
model: 'GOLDEN-WASHER-COMPOSITE',
|
||||
area_id: 'golden_appliance',
|
||||
identifiers: [['houseplan_golden', washerId]],
|
||||
config_entries: ['golden_entry'],
|
||||
entry_type: null,
|
||||
via_device_id: null,
|
||||
disabled_by: null,
|
||||
};
|
||||
const addWasherEntity = (entityId, state, attributes = {}, registry = {}) => {
|
||||
entities[entityId] = {
|
||||
entity_id: entityId,
|
||||
device_id: washerId,
|
||||
platform: 'houseplan_golden',
|
||||
config_entry_id: 'golden_entry',
|
||||
if (includeAppliance) {
|
||||
const washerId = 'golden-washer';
|
||||
devices[washerId] = {
|
||||
id: washerId,
|
||||
name: 'Golden washing machine',
|
||||
model: 'GOLDEN-WASHER-COMPOSITE',
|
||||
area_id: 'golden_appliance',
|
||||
identifiers: [['houseplan_golden', washerId]],
|
||||
config_entries: ['golden_entry'],
|
||||
entry_type: null,
|
||||
via_device_id: null,
|
||||
disabled_by: null,
|
||||
...registry,
|
||||
};
|
||||
states[entityId] = {
|
||||
entity_id: entityId,
|
||||
state,
|
||||
attributes: { friendly_name: registry.original_name || entityId, ...attributes },
|
||||
const addWasherEntity = (entityId, state, attributes = {}, registry = {}) => {
|
||||
entities[entityId] = {
|
||||
entity_id: entityId,
|
||||
device_id: washerId,
|
||||
platform: 'houseplan_golden',
|
||||
config_entry_id: 'golden_entry',
|
||||
disabled_by: null,
|
||||
...registry,
|
||||
};
|
||||
states[entityId] = {
|
||||
entity_id: entityId,
|
||||
state,
|
||||
attributes: { friendly_name: registry.original_name || entityId, ...attributes },
|
||||
};
|
||||
};
|
||||
};
|
||||
addWasherEntity('switch.golden_washer_power', 'on', {}, { original_name: 'Power' });
|
||||
addWasherEntity('switch.golden_washer_child_lock', 'off', {}, { original_name: 'Child lock' });
|
||||
addWasherEntity('sensor.golden_washer_status', 'done', {}, {
|
||||
original_name: 'Status', translation_key: 'status',
|
||||
});
|
||||
addWasherEntity('sensor.golden_washer_stage', 'Rinse', {}, { original_name: 'Stage' });
|
||||
addWasherEntity('sensor.golden_washer_program', 'mixed_wash', {}, { original_name: 'Program' });
|
||||
layout[washerId] = { s: 'golden-appliance', x: 0.5, y: 0.5 };
|
||||
addWasherEntity('switch.golden_washer_power', 'on', {}, { original_name: 'Power' });
|
||||
addWasherEntity('switch.golden_washer_child_lock', 'off', {}, { original_name: 'Child lock' });
|
||||
addWasherEntity('sensor.golden_washer_status', 'done', {}, {
|
||||
original_name: 'Status', translation_key: 'status',
|
||||
});
|
||||
addWasherEntity('sensor.golden_washer_stage', 'Rinse', {}, { original_name: 'Stage' });
|
||||
addWasherEntity('sensor.golden_washer_program', 'mixed_wash', {}, { original_name: 'Program' });
|
||||
layout[washerId] = { s: 'golden-appliance', x: 0.5, y: 0.5 };
|
||||
}
|
||||
return { devices, entities, states, layout, areas };
|
||||
};
|
||||
|
||||
export const VISUAL_MATRIX_COUNTS = Object.freeze({
|
||||
spaces: 3,
|
||||
rooms: geometryRooms.length + lightingRooms.length + applianceRooms.length,
|
||||
spaces: 2,
|
||||
rooms: geometryRooms.length + lightingRooms.length,
|
||||
openings: geometrySpace.openings.length + lightingSpace.openings.length,
|
||||
partitions: geometrySpace.partitions.length + lightingSpace.partitions.length,
|
||||
columns: geometrySpace.wall_columns.length + lightingSpace.wall_columns.length,
|
||||
});
|
||||
|
||||
export const makeVisualMatrixFixture = () => ({
|
||||
export const makeVisualMatrixFixture = ({ applianceLifecycle = false } = {}) => ({
|
||||
config: {
|
||||
spaces: [
|
||||
structuredClone(geometrySpace), structuredClone(lightingSpace),
|
||||
structuredClone(applianceSpace),
|
||||
...(applianceLifecycle ? [structuredClone(applianceSpace)] : []),
|
||||
],
|
||||
// A persisted marker is part of the fixture contract for scenarios that
|
||||
// override per-source Glow controls. The device/layout alone are not a
|
||||
@@ -264,6 +266,10 @@ export const makeVisualMatrixFixture = () => ({
|
||||
},
|
||||
},
|
||||
},
|
||||
...runtime(),
|
||||
counts: VISUAL_MATRIX_COUNTS,
|
||||
...runtime(applianceLifecycle),
|
||||
counts: applianceLifecycle ? {
|
||||
...VISUAL_MATRIX_COUNTS,
|
||||
spaces: VISUAL_MATRIX_COUNTS.spaces + 1,
|
||||
rooms: VISUAL_MATRIX_COUNTS.rooms + applianceRooms.length,
|
||||
} : VISUAL_MATRIX_COUNTS,
|
||||
});
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { makeLargeHouseFixture } from '../fixtures/large-house.mjs';
|
||||
import { fixtureWallKey, makeVisualMatrixFixture } from '../fixtures/visual-matrix.mjs';
|
||||
|
||||
const fixtureFor = (name) => name === 'large' ? makeLargeHouseFixture() : makeVisualMatrixFixture();
|
||||
const fixtureFor = (scenario) => scenario.fixture === 'large'
|
||||
? makeLargeHouseFixture()
|
||||
: makeVisualMatrixFixture({ applianceLifecycle: !!scenario.applianceLifecycle });
|
||||
|
||||
const themeVars = {
|
||||
dark: {
|
||||
@@ -50,7 +52,7 @@ async function stableEnvironment(page, scenario) {
|
||||
|
||||
/** Apply every data-only scenario override before the fixture crosses into the browser. */
|
||||
export function prepareGoldenFixture(scenario) {
|
||||
const fixture = fixtureFor(scenario.fixture);
|
||||
const fixture = fixtureFor(scenario);
|
||||
if (scenario.cornerSplitWall) {
|
||||
const stage = scenario.cornerSplitWall;
|
||||
if (!['before', 'thin', 'thick'].includes(stage))
|
||||
|
||||
@@ -35,10 +35,12 @@ export const GOLDEN_SCENARIOS = Object.freeze([
|
||||
theme: 'dark', viewport: { width: 1000, height: 900 }, ...stage },
|
||||
{ id: 'geometry-view-light-fit', fixture: 'visual', space: 'golden-geometry', mode: 'view',
|
||||
theme: 'light', viewport: { width: 1000, height: 900 }, ...stage },
|
||||
{ id: 'washer-active-cycle-dark', fixture: 'visual', space: 'golden-appliance', mode: 'view',
|
||||
{ id: 'washer-active-cycle-dark', fixture: 'visual', applianceLifecycle: true,
|
||||
space: 'golden-appliance', mode: 'view',
|
||||
stateOverrides: { 'sensor.golden_washer_status': { state: 'start' } },
|
||||
theme: 'dark', viewport: { width: 1000, height: 900 }, ...stage },
|
||||
{ id: 'washer-idle-cycle-dark', fixture: 'visual', space: 'golden-appliance', mode: 'view',
|
||||
{ id: 'washer-idle-cycle-dark', fixture: 'visual', applianceLifecycle: true,
|
||||
space: 'golden-appliance', mode: 'view',
|
||||
stateOverrides: { 'sensor.golden_washer_status': { state: 'done' } },
|
||||
theme: 'dark', viewport: { width: 1000, height: 900 }, ...stage },
|
||||
{ id: 'day-cycle-dawn-dark', fixture: 'visual', space: 'golden-geometry', mode: 'view',
|
||||
|
||||
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 343 KiB After Width: | Height: | Size: 342 KiB |
|
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 328 KiB |
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 282 KiB |
|
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 290 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"fixture": "synthetic-only",
|
||||
"sourceFingerprint": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"sourceFingerprint": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"captureScriptSha256": "34f2219790d46efd8250e7a1bd829cb8fc0b0547e1260635fefa52407551b41b",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "d78868e4a9866ce624ddc7ecb73da3de0ea69889a5b2555304e3071d0d384277"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "d36b6f9f8139f31ef73a780c6511a640a26055efd9d7a24c24fd48b1d8379bf0"
|
||||
},
|
||||
"view-touch": {
|
||||
"file": "02-view-touch.png",
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "358e25ff9984d0fb0c03cfbb848df40c425fdfe64cd5f4f613b1e754ca9d4249"
|
||||
},
|
||||
"space-create": {
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "c53db2e5c642a5549c13f3c93a5b359fed69bdb2621bf71a243a877ffcb95e6b"
|
||||
},
|
||||
"room-contour-close": {
|
||||
@@ -46,8 +46,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "f8196be86dca7b39580b23ced0fce67c18b1fb30ddc2320232da7a7caa372129"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "2f4770869f04c8d7f1e8ff33af1e8bd79f45ad6d97be6d5e6135b3a82fec9e4c"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
"file": "05-plan-context-tray.png",
|
||||
@@ -57,8 +57,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "14bef4778e0927956a4dc0d132bc814c8fd1ea427f42d98c0aec9699a7918d7f"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "47d8fc2ac1c14cb699e990ca9c00d89b9ac57f6cc76b40420ceb26b4d7f50df4"
|
||||
},
|
||||
"device-editor": {
|
||||
"file": "06-device-editor.png",
|
||||
@@ -68,8 +68,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "b3bfcf1249a9228c538760fe59852c99aaaca4f33355ce3dfa554d2e7c54ed5b"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "7c3e25534fc819c45431907616c3d523961505859ee68af27cce2daec9f04fb0"
|
||||
},
|
||||
"device-display-preview": {
|
||||
"file": "06-device-display-preview.png",
|
||||
@@ -79,8 +79,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "e47d1bb71c58c9f9cc62792ca53d1db9c3bf989e13275c25b5dd25e0427d5717"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "df3a54395c83bffd7a161f1fb3de0143e12e76567535aedf9883873ead74df91"
|
||||
},
|
||||
"background-editor": {
|
||||
"file": "07-background-editor.png",
|
||||
@@ -90,8 +90,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "d957c01e5261d7c264faed8a157011606b373f5026c7154e49511ae4864260e0"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "4e7b3b1220a3fe104cf11e5b32a31b343dc95c45fd2cbe3365d145f0a66a560d"
|
||||
},
|
||||
"room-card": {
|
||||
"file": "08-room-card.png",
|
||||
@@ -101,8 +101,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "5d4bd13ec234a58e9ec12ff0e73ff1c8d96cb16b5426850f63e4195c03a96f6f"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "176abba71d41cfb045a33f82a794d9fbb2a5d3c48e6df66e6ec3a8e448311b11"
|
||||
},
|
||||
"device-info": {
|
||||
"file": "09-device-info.png",
|
||||
@@ -112,8 +112,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "c21b9b9c8e62502d59b35e7d5c6a6327b5e93243a35f4b00b0e4f048a1174d2f",
|
||||
"imageSha256": "b0557546e1d2075b62eea36dbd105a5c8ee59be4c0e972b5aef0a07e38776115"
|
||||
"sourceSha256": "15d1ebb8e22290b7d945597c86b9cda6de2fc3abfd7c7948428a8a5d7fd28706",
|
||||
"imageSha256": "2199ed88b215bf2bff63bf665028f78b2aa6a92c3032b803931790f2ef071893"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,8 @@ test('washer lifecycle goldens pair active and idle snapshots of one composite f
|
||||
assert.ok(idle);
|
||||
assert.equal(active.space, 'golden-appliance');
|
||||
assert.equal(idle.space, active.space);
|
||||
assert.equal(active.applianceLifecycle, true);
|
||||
assert.equal(idle.applianceLifecycle, true);
|
||||
assert.equal(active.stateOverrides['sensor.golden_washer_status'].state, 'start');
|
||||
assert.equal(idle.stateOverrides['sensor.golden_washer_status'].state, 'done');
|
||||
for (const scenario of [active, idle]) {
|
||||
|
||||