Model/backend/magic_plan/models.py
2026-04-28 15:36:27 +00:00

219 lines
4.7 KiB
Python

from dataclasses import dataclass
from typing import Optional
@dataclass
class MagicPlanRoomPoint:
snapped_x: float
snapped_y: float
height: float
uid: str
values: dict[str, str] # e.g. loadBearingWall, addElevationToReport
@dataclass
class MagicPlanWallPoint:
"""Point in <exploded><wall> — absolute coords, no uid or values."""
x: float
y: float
height: float
@dataclass
class MagicPlanDoor:
"""Door in <floorRoom> context — wall-relative position."""
wall_point_index: int
type: str
u: float
width: float # m
depth: float # m
height: float # m
orientation: int
snapped_type: str
snapped_position: float
snapped_width: float # m
snapped_depth: float # m
snapped_height: float # m
snapped_orientation: int
inset_x: float
inset_y: float
inset_z: float
symbol_instance: str
twin_wall_item_uid: Optional[str] = None
@dataclass
class MagicPlanWindow:
"""Window in <floorRoom> context — wall-relative position."""
wall_point_index: int
type: str
u: float
width: float # m
depth: float # m
height: float # m
orientation: int
snapped_type: str
snapped_position: float
snapped_width: float # m
snapped_depth: float # m
snapped_height: float # m
snapped_orientation: int
inset_x: float
inset_y: float
inset_z: float
symbol_instance: str
@dataclass
class MagicPlanExplodedOpening:
"""Door or window in <exploded> context — absolute coords, no snapped* fields."""
type: str
x1: float
y1: float
x2: float
y2: float
width: float # m
depth: float # m
height: float # m
inset_x: float
inset_y: float
orientation: int
symbol_instance: str
@dataclass
class MagicPlanFurniture:
type: str
x: float
y: float
snapped_x: float
snapped_y: float
angle: float
width: float # m
depth: float # m
height: float # m
snapped_width: float # m
snapped_depth: float # m
snapped_height: float # m
size_lock_0: str
size_lock_1: str
size_lock_2: str
symbol_instance: str
@dataclass
class MagicPlanMainDimension:
from_point: int
to_point: int
dir_x: float
dir_y: float
value: float
actual_value: float
is_set: bool
@dataclass
class MagicPlanExplodedWall:
wall_type: str # "exterior" | "interior"
points: list[MagicPlanWallPoint]
@dataclass
class MagicPlanExploded:
walls: list[MagicPlanExplodedWall]
doors: list[MagicPlanExplodedOpening]
windows: list[MagicPlanExplodedOpening]
furniture: list[MagicPlanFurniture]
@dataclass
class MagicPlanSymbolInstance:
id: str
uid: str
parent_uid: str
symbol: str
values: dict[str, str] # ceilingHeight, width, height, depth, distanceUnit, etc.
@dataclass
class MagicPlanRoom:
uid: str
type: str
x: float
y: float
rotation: float
was_modified: bool
linked_room_0: str
linked_room_1: str
area: float # m²
perimeter: float # m
values: dict[str, str] # ceilingHeight, label, etc.
points: list[MagicPlanRoomPoint]
doors: list[MagicPlanDoor]
windows: list[MagicPlanWindow]
furniture: list[MagicPlanFurniture]
main_dimensions: list[MagicPlanMainDimension]
@dataclass
class MagicPlanFloor:
uid: str
name: str
floor_type: str # "0"=ground, "1"=upper, "2"=basement
rotation: float
compass_angle: float
area_without_walls: float # m²
area_with_interior_walls_only: float # m²
area_with_walls: float # m²
symbol_instance: MagicPlanSymbolInstance
rooms: list[MagicPlanRoom]
furniture: list[MagicPlanFurniture] # floor-level furniture (not inside any room)
exploded: MagicPlanExploded
@dataclass
class MagicPlanSummary:
"""Plan metadata returned by the list-plans API endpoint."""
id: str
project_id: str
name: str
address: str
creation_date: str
update_date: str
workgroup_id: str
team_id: str
created_by: str
thumbnail_url: str
public_url: str
cloud_url: str
url_3d: str
@dataclass
class MagicPlanDetail:
"""Full plan response: summary metadata + parsed XML plan."""
summary: MagicPlanSummary
plan_xml: "MagicPlanPlan"
@dataclass
class MagicPlanPlan:
id: str
uid: str
name: str
type: str
interior_wall_width: float # m
exterior_wall_width: float # m
schematic: bool
has_land_survey_address: bool
last_patch_identifier: str
last_roll_identifier: str
values: dict[str, str] # date, statistics.*, distanceUnit, etc.
floors: list[MagicPlanFloor]
interior_room_floors: list[MagicPlanFloor] # from <interiorRoomPoints>