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 — absolute coords, no uid or values.""" x: float y: float height: float @dataclass class MagicPlanDoor: """Door in context — wall-relative position.""" wall_point_index: int type: str u: float # position along wall (0-1) 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 context — wall-relative position.""" wall_point_index: int type: str u: float # position along wall (0-1) 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 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 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