feat v1.23.0: doors & windows with live open/lock state

New markup tool 'Opening': click a wall — the opening snaps onto the nearest DERIVED
room wall (v1.19.0 model: openings keep absolute coords, so room edits never break
them) and takes its angle. Dialog: type, length in real cm (door 90 / window 120 —
per-space scale makes it honest), contact sensor (invertible), lock (doors).
Rendering after easy-floorplan (MIT): hinged leaf + swing arc drawing on via
stroke-dashoffset; window = two casements. No sensor → static plan defaults (door
open, window closed); unavailable freezes the default (pure openingAmount, tested).
Lock: padlock badge (green locked / orange unlocked / grey unknown); the lock is
never toggled from the plan — clicking shows an info card with both states.
snapToWall + openingAmount in logic.ts; space.openings validated server-side.
+2 tests (76). Verified live on the dacha (real TTLock + TRV window sensor).
This commit is contained in:
Matysh
2026-07-17 07:21:20 +03:00
parent 7c9731655e
commit ff7c1b883c
16 changed files with 1063 additions and 197 deletions
+21
View File
@@ -36,6 +36,27 @@
"markup.add": "Add",
"markup.merge": "Merge",
"markup.split": "Split",
"markup.opening": "Opening",
"title.markup_opening": "Doors & windows: click a wall to place, click an opening to edit",
"opening.new": "New opening",
"opening.edit": "Door / window",
"opening.door": "Door",
"opening.window": "Window",
"opening.type_label": "Type",
"opening.length_label": "Length, cm",
"opening.contact_label": "Open/close sensor",
"opening.lock_label": "Lock",
"opening.none": "— none —",
"opening.invert": "Invert open/closed",
"opening.flip_h": "Hinge on the other jamb",
"opening.flip_v": "Opens to the other side",
"opening.open": "Open",
"opening.closed": "Closed",
"opening.locked": "Locked",
"opening.unlocked": "Unlocked",
"opening.state_unknown": "unavailable",
"opening.no_entities": "No sensors bound — a static symbol on the plan.",
"toast.opening_no_wall": "Click next to a room wall — openings sit on walls",
"markup.delete": "Delete",
"markup.hint_points": "points: {n} · Esc/Ctrl+Z — undo a dot · close the outline by clicking the first one",
"markup.hint_start": "click a grid dot to start the outline",