import json from collections import defaultdict from sqlalchemy import create_engine, text # šŸ”§ Adjust this to your environment DB_URL = "postgresql+psycopg2://postgres:postgres@192.168.1.86:5432/digital_aeros_fixed" def export_rbd_json(project_id, output_file="rbd.json"): engine = create_engine(DB_URL) with engine.connect() as conn: # --- Project info --- project = conn.execute( text('SELECT "ProjectId","ProjectName" FROM public."Projects" WHERE "ProjectId" = :pid'), {"pid": project_id} ).mappings().first() if not project: raise ValueError(f"āŒ Project {project_id} not found") print(f"šŸ” Loaded project: {project['ProjectName']} (ID={project_id})") # --- Schematics --- schematics = conn.execute( text('SELECT "SchematicId","SchematicName" FROM public."Schematics" WHERE "ProjectId" = :pid'), {"pid": project_id} ).mappings().all() all_schematics_json = {} for s in schematics: sid = s["SchematicId"] sname = s["SchematicName"] print(f"\n=== Processing schematic {sid} ({sname}) ===") # --- Nodes --- nodes_data = conn.execute( text('SELECT "NodeId","NodeUIId","NodeName","NodeTypeCode" ' 'FROM public."RegularNodes" WHERE "SchematicId" = :sid'), {"sid": sid} ).mappings().all() # dict keyed by NodeId nodes = {str(n["NodeId"]): dict(n) for n in nodes_data} # map UIId -> NodeId uiid_to_id = {str(n["NodeUIId"]): str(n["NodeId"]) for n in nodes_data} print(f"🟦 Nodes: {len(nodes)}") # --- Connectors (edges) --- edges = conn.execute( text('SELECT "SourceUIId","SinkUIId" FROM public."Connectors" WHERE "SchematicId" = :sid'), {"sid": sid} ).mappings().all() children_map = defaultdict(list) for e in edges: src_ui = str(e["SourceUIId"]) sink_ui = str(e["SinkUIId"]) if src_ui in uiid_to_id and sink_ui in uiid_to_id: src_id = uiid_to_id[src_ui] sink_id = uiid_to_id[sink_ui] children_map[src_id].append(sink_id) print(f"šŸ”— Connectors: {len(edges)}") # --- Redundancies --- redundancies = conn.execute( text('SELECT * FROM public."Redundancies" WHERE "SchematicId" = :sid'), {"sid": sid} ).mappings().all() states = conn.execute( text('SELECT * FROM public."RedundancyStates" WHERE "RedundancyId" IN ' '(SELECT "RedundancyId" FROM public."Redundancies" WHERE "SchematicId" = :sid)'), {"sid": sid} ).mappings().all() state_cells = conn.execute( text('SELECT * FROM public."RedundancyStateCells" WHERE "RedundancyStateId" IN ' '(SELECT "StateId" FROM public."RedundancyStates" WHERE "RedundancyId" IN ' '(SELECT "RedundancyId" FROM public."Redundancies" WHERE "SchematicId" = :sid))'), {"sid": sid} ).mappings().all() # Build redundancy structure redundancy_map = {} for r in redundancies: rid = str(r["RedundancyId"]) redundancy_map[rid] = { "name": r["RedundancyName"], "type": "standby" if r["IsKNStandby"] else "kofn", "min_required": r["MinRequiredNodes"], "switch_delay": r["SwitchDelay"], "states": {} } for st in states: sid2 = str(st["StateId"]) rid = str(st["RedundancyId"]) redundancy_map[rid]["states"][sid2] = { "priority": st["StatePriority"], "duration": st["StateDuration"], "cells": [] } for c in state_cells: sid2 = str(c["RedundancyStateId"]) for r_id, r in redundancy_map.items(): if sid2 in r["states"]: node_id = str(c["InvolvedNodeId"]) if node_id in nodes: # only link if valid r["states"][sid2]["cells"].append({ "node_id": node_id, "status": c["NodeStatusCode"] }) break # --- Build JSON nodes --- json_nodes = {} for node_id, n in nodes.items(): node_type = str(n["NodeTypeCode"]).lower() node_json = { "type": node_type, "name": n["NodeName"], "children": children_map.get(node_id, []), # now NodeId-based "availability": 1.0 # āœ… default availability } json_nodes[node_id] = node_json # --- Root detection --- all_children = {c for lst in children_map.values() for c in lst} root_candidates = [nid for nid in nodes.keys() if nid not in all_children] root = root_candidates[0] if root_candidates else None print(f"🌳 Root node detected: {root}") # --- Assemble schematic JSON --- schematic_json = { "schematic_id": sid, "schematic_name": sname, "root": str(root) if root else None, "nodes": json_nodes, "redundancies": redundancy_map } all_schematics_json[str(sid)] = schematic_json print(f"āœ… Finished schematic {sid}") # --- Final JSON --- final_json = { "project_id": project["ProjectId"], "project_name": project["ProjectName"], "schematics": all_schematics_json } with open(output_file, "w") as f: json.dump(final_json, f, indent=2) print(f"\nšŸŽ‰ Exported simplified RBD JSON (NodeId-based, availability=1.0) " f"for Project {project_id} → {output_file}") if __name__ == "__main__": export_rbd_json(project_id=70, output_file="project_70_rbd.json")