642 lines
34 KiB
Python
642 lines
34 KiB
Python
# topology_api/seed/seed_ghc01_to_ghc05.py
|
||
"""
|
||
Seed the topology database with GHC-01 through GHC-05 mission data.
|
||
Idempotent: can be run multiple times safely.
|
||
|
||
Usage:
|
||
PYTHONPATH="d:/My Coding Project/KSP_Project" python topology_api/seed/seed_ghc01_to_ghc05.py
|
||
"""
|
||
import json
|
||
from datetime import datetime, timezone
|
||
from topology_api.db import write_cursor
|
||
|
||
UTC = timezone.utc
|
||
|
||
|
||
def ts(s):
|
||
"""Parse ISO timestamp string to datetime."""
|
||
return datetime.fromisoformat(s).replace(tzinfo=UTC)
|
||
|
||
|
||
def seed():
|
||
with write_cursor() as cur:
|
||
# ============================================================
|
||
# PHASE 0: Clean existing data (reverse dependency order)
|
||
# ============================================================
|
||
cur.execute("DELETE FROM diagram_nodes")
|
||
cur.execute("DELETE FROM diagram_layouts")
|
||
cur.execute("DELETE FROM topology_connections")
|
||
cur.execute("DELETE FROM component_states")
|
||
cur.execute("DELETE FROM component_versions")
|
||
cur.execute("DELETE FROM ports")
|
||
cur.execute("DELETE FROM components")
|
||
cur.execute("DELETE FROM mission_events")
|
||
cur.execute("DELETE FROM missions")
|
||
cur.execute("DELETE FROM bases")
|
||
print("Cleared existing data.")
|
||
|
||
# ============================================================
|
||
# PHASE 1: Base
|
||
# ============================================================
|
||
cur.execute("""
|
||
INSERT INTO bases (id, code, name, description)
|
||
VALUES (gen_random_uuid(), 'guanghan', '广寒基地',
|
||
'月球东方海常驻月面基地')
|
||
ON CONFLICT (code) DO UPDATE SET name = EXCLUDED.name
|
||
RETURNING id
|
||
""")
|
||
base_id = cur.fetchone()["id"]
|
||
print(f"Base: guanghan ({base_id})")
|
||
|
||
# ============================================================
|
||
# PHASE 2: Missions
|
||
# ============================================================
|
||
mission_specs = [
|
||
("BL-01", "冰轮部署任务-01"),
|
||
("GHC-01", "广寒基地建设任务-01"),
|
||
("JC-01", "金蟾部署任务-01"),
|
||
("BL-02", "冰轮部署任务-02"),
|
||
("GHC-02", "广寒基地建设任务-02"),
|
||
("GHC-03", "广寒基地建设任务-03"),
|
||
("BL-03", "冰轮部署任务-03"),
|
||
("GHC-04", "广寒基地建设任务-04"),
|
||
("GHC-05", "广寒基地建设任务-05"),
|
||
]
|
||
mission_ids = {}
|
||
for code, title in mission_specs:
|
||
cur.execute("""
|
||
INSERT INTO missions (id, base_id, code, title, occurrence_status)
|
||
VALUES (gen_random_uuid(), %(base)s, %(code)s, %(title)s, 'occurred')
|
||
ON CONFLICT (base_id, code) DO UPDATE SET title = EXCLUDED.title
|
||
RETURNING id
|
||
""", {"base": base_id, "code": code, "title": title})
|
||
mission_ids[code] = cur.fetchone()["id"]
|
||
print(f"Missions: {len(mission_ids)}")
|
||
|
||
# ============================================================
|
||
# PHASE 3: Mission Events
|
||
# ============================================================
|
||
def add_event(mission_code, effective_at, event_order, event_type, title,
|
||
details=None, source_ref=None):
|
||
cur.execute("""
|
||
INSERT INTO mission_events
|
||
(id, mission_id, effective_at, event_order, event_type,
|
||
title, details, source_ref)
|
||
VALUES (gen_random_uuid(), %(mid)s, %(at)s, %(ord)s, %(typ)s,
|
||
%(title)s, %(det)s, %(ref)s)
|
||
ON CONFLICT (mission_id, effective_at, event_order) DO NOTHING
|
||
RETURNING id
|
||
""", {
|
||
"mid": mission_ids[mission_code], "at": effective_at,
|
||
"ord": event_order, "typ": event_type, "title": title,
|
||
"det": json.dumps(details) if details else None,
|
||
"ref": source_ref,
|
||
})
|
||
row = cur.fetchone()
|
||
if row:
|
||
return row["id"]
|
||
cur.execute("""
|
||
SELECT id FROM mission_events
|
||
WHERE mission_id = %(mid)s AND effective_at = %(at)s
|
||
AND event_order = %(ord)s
|
||
""", {"mid": mission_ids[mission_code], "at": effective_at, "ord": event_order})
|
||
return cur.fetchone()["id"]
|
||
|
||
events = {}
|
||
|
||
# ---- BL-01 ----
|
||
events["BL-01_0"] = add_event("BL-01",
|
||
ts("2024-04-19T22:58:00Z"), 0, "component_introduced",
|
||
"冰轮一号着陆东方海", source_ref="Timeline.md BL-01")
|
||
events["BL-01_terminal"] = add_event("BL-01",
|
||
ts("2024-05-17T23:01:00Z"), 1, "mission_checkpoint",
|
||
"BL-01任务最后记录", source_ref="Timeline.md BL-01末条记录")
|
||
|
||
# ---- GHC-01 ----
|
||
events["GHC-01_0"] = add_event("GHC-01",
|
||
ts("2024-06-16T07:23:00Z"), 0, "component_introduced",
|
||
"广寒核心舱着陆东方海,引擎模块分离坠毁", source_ref="Timeline.md GHC-01")
|
||
|
||
# ---- BL-02 ----
|
||
events["BL-02_0"] = add_event("BL-02",
|
||
ts("2024-06-23T05:23:00Z"), 0, "component_introduced",
|
||
"冰轮二号着陆东方海(核心舱以东112米)", source_ref="Timeline.md BL-02")
|
||
|
||
# ---- JC-01 (mission only, no components in M1) ----
|
||
events["JC-01_0"] = add_event("JC-01",
|
||
ts("2024-06-17T08:19:00Z"), 0, "component_introduced",
|
||
"金蟾一号部署至LEO 400×400 km(轨道资产,M1不录入组件)",
|
||
source_ref="Timeline.md JC-01")
|
||
|
||
# ---- GHC-02 ----
|
||
events["GHC-02_0"] = add_event("GHC-02",
|
||
ts("2024-07-01T10:37:00Z"), 0, "connection_established",
|
||
"冰轮一号与冰轮二号通过柔性管道完成燃料连接",
|
||
source_ref="Timeline.md GHC-02 EVA-1")
|
||
events["GHC-02_terminal"] = add_event("GHC-02",
|
||
ts("2024-07-15T03:16:00Z"), 1, "mission_checkpoint",
|
||
"GHC-02任务最后记录", source_ref="Timeline.md GHC-02末条记录")
|
||
|
||
# ---- GHC-03 ----
|
||
events["GHC-03_0"] = add_event("GHC-03",
|
||
ts("2024-08-15T23:51:00Z"), 0, "component_introduced",
|
||
"电力模块搭载广寒01模块着陆东方海", source_ref="Timeline.md GHC-03")
|
||
events["GHC-03_1"] = add_event("GHC-03",
|
||
ts("2024-08-17T00:00:00Z"), 1, "component_installed",
|
||
"电力模块存储支架安装至电力模块北部",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-03 EVA-6")
|
||
events["GHC-03_2"] = add_event("GHC-03",
|
||
ts("2024-08-18T00:00:00Z"), 2, "component_installed",
|
||
"核反应堆、ISRU模块、采矿模块、矿石/燃料存储模块安装完成",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-03 EVA-7/8")
|
||
events["GHC-03_3"] = add_event("GHC-03",
|
||
ts("2024-08-19T00:00:00Z"), 3, "connection_established",
|
||
"核心舱南侧与电力模块北部建立结构直连",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-03 EVA-8")
|
||
events["GHC-03_4"] = add_event("GHC-03",
|
||
ts("2024-08-19T00:00:00Z"), 4, "state_changed",
|
||
"核反应堆以15%功率开始运行",
|
||
details={"time_precision": "date", "power_percent": 15},
|
||
source_ref="Timeline.md GHC-03")
|
||
events["GHC-03_terminal"] = add_event("GHC-03",
|
||
ts("2024-08-30T12:45:00Z"), 5, "mission_checkpoint",
|
||
"GHC-03任务最后记录", source_ref="Timeline.md GHC-03末条记录")
|
||
|
||
# ---- BL-03 ----
|
||
events["BL-03_0"] = add_event("BL-03",
|
||
ts("2024-09-23T19:20:00Z"), 0, "component_introduced",
|
||
"冰轮三号(首艘Block 2)着陆东方海", source_ref="Timeline.md BL-03")
|
||
|
||
# ---- GHC-04 ----
|
||
events["GHC-04_0"] = add_event("GHC-04",
|
||
ts("2024-10-25T00:00:00Z"), 0, "component_installed",
|
||
"核燃料存储模块安装至电力模块东部",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-7")
|
||
events["GHC-04_1"] = add_event("GHC-04",
|
||
ts("2024-10-27T00:00:00Z"), 1, "component_installed",
|
||
"离心机模块吊装至电力模块顶部安装位",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-9")
|
||
events["GHC-04_2"] = add_event("GHC-04",
|
||
ts("2024-10-31T00:00:00Z"), 2, "connection_removed",
|
||
"冰轮一号与冰轮二号之间燃料连接断开(为跳跃做准备)",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-13")
|
||
events["GHC-04_3"] = add_event("GHC-04",
|
||
ts("2024-11-03T00:00:00Z"), 3, "state_changed",
|
||
"核反应堆升至100%功率,ISRU全功率运行",
|
||
details={"time_precision": "date", "power_percent": 100},
|
||
source_ref="Timeline.md GHC-04")
|
||
events["GHC-04_4"] = add_event("GHC-04",
|
||
ts("2024-11-05T00:00:00Z"), 4, "connection_established",
|
||
"冰轮一号接入基地统一燃料/电力网络",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-14")
|
||
events["GHC-04_5"] = add_event("GHC-04",
|
||
ts("2024-11-06T00:00:00Z"), 5, "connection_established",
|
||
"冰轮二号接入基地统一燃料/电力网络",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-15")
|
||
events["GHC-04_6"] = add_event("GHC-04",
|
||
ts("2024-11-08T00:00:00Z"), 6, "connection_established",
|
||
"冰轮三号接入基地统一燃料/电力网络",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-16")
|
||
events["GHC-04_terminal"] = add_event("GHC-04",
|
||
ts("2024-11-20T13:57:00Z"), 7, "mission_checkpoint",
|
||
"GHC-04任务最后记录", source_ref="Timeline.md GHC-04末条记录")
|
||
|
||
# ---- GHC-05 ----
|
||
events["GHC-05_0"] = add_event("GHC-05",
|
||
ts("2024-12-14T04:21:00Z"), 0, "component_introduced",
|
||
"吴刚二号着陆东方海广寒基地(手动模式)", source_ref="Timeline.md GHC-05")
|
||
events["GHC-05_1"] = add_event("GHC-05",
|
||
ts("2024-12-23T01:11:00Z"), 1, "component_introduced",
|
||
"广寒03模块(温室+居住舱段一号+居住舱段二号+实验舱段)由冰轮三号运抵月面",
|
||
source_ref="Timeline.md GHC-05")
|
||
events["GHC-05_2"] = add_event("GHC-05",
|
||
ts("2024-12-26T00:00:00Z"), 2, "connection_removed",
|
||
"核心舱南侧与电力模块北部结构直连断开(为舱段安装腾出三号位)",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-8")
|
||
events["GHC-05_3"] = add_event("GHC-05",
|
||
ts("2024-12-27T00:00:00Z"), 3, "component_installed",
|
||
"温室舱段安装至核心舱四号位(西侧),手动展开至工作构型",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-9")
|
||
events["GHC-05_4"] = add_event("GHC-05",
|
||
ts("2024-12-28T00:00:00Z"), 4, "component_installed",
|
||
"居住舱段一号安装至核心舱三号位(南侧),电力模块经加压走道连接至居住舱段一号远端",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-10")
|
||
events["GHC-05_5"] = add_event("GHC-05",
|
||
ts("2024-12-29T00:00:00Z"), 5, "component_installed",
|
||
"居住舱段二号安装至核心舱一号位(北侧)",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-11")
|
||
events["GHC-05_6"] = add_event("GHC-05",
|
||
ts("2024-12-30T00:00:00Z"), 6, "component_installed",
|
||
"实验舱段安装至核心舱二号位(东侧),启动航电和环控回路",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-12")
|
||
events["GHC-05_7"] = add_event("GHC-05",
|
||
ts("2024-12-31T00:00:00Z"), 7, "connection_established",
|
||
"吴刚二号通过加压走道连接至温室舱段远端接口",
|
||
details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-13")
|
||
events["GHC-05_8"] = add_event("GHC-05",
|
||
ts("2025-01-02T00:00:00Z"), 8, "state_changed",
|
||
"核反应堆功率调整至30%,全基地整合验证完成",
|
||
details={"time_precision": "date", "power_percent": 30},
|
||
source_ref="Timeline.md GHC-05 EVA-15")
|
||
events["GHC-05_terminal"] = add_event("GHC-05",
|
||
ts("2025-01-22T10:52:00Z"), 9, "mission_checkpoint",
|
||
"GHC-05任务最后记录", source_ref="Timeline.md GHC-05末条记录")
|
||
|
||
print(f"Events: {len(events)}")
|
||
|
||
# ============================================================
|
||
# PHASE 4: Components
|
||
# ============================================================
|
||
def add_component(component_key, component_type, introduced_event_key,
|
||
metadata=None):
|
||
cur.execute("""
|
||
INSERT INTO components
|
||
(id, base_id, component_key, component_type,
|
||
introduced_by_event_id, metadata)
|
||
VALUES (gen_random_uuid(), %(base)s, %(key)s, %(typ)s,
|
||
%(ev)s, %(meta)s)
|
||
ON CONFLICT (base_id, component_key) DO NOTHING
|
||
RETURNING id
|
||
""", {
|
||
"base": base_id, "key": component_key, "typ": component_type,
|
||
"ev": events[introduced_event_key],
|
||
"meta": json.dumps(metadata) if metadata else None,
|
||
})
|
||
row = cur.fetchone()
|
||
if row:
|
||
return row["id"]
|
||
cur.execute(
|
||
"SELECT id FROM components WHERE base_id = %(base)s AND component_key = %(key)s",
|
||
{"base": base_id, "key": component_key})
|
||
return cur.fetchone()["id"]
|
||
|
||
comp = {}
|
||
|
||
comp["core_cabin"] = add_component("core_cabin", "module", "GHC-01_0",
|
||
metadata={"dryMassT": 28.2, "batteryKwh": 50, "dockingNodes": 4})
|
||
comp["binglun_1"] = add_component("binglun_1", "vehicle", "BL-01_0",
|
||
metadata={"block": 1, "role": "fuel_transport"})
|
||
comp["binglun_2"] = add_component("binglun_2", "vehicle", "BL-02_0",
|
||
metadata={"block": 1, "role": "fuel_transport"})
|
||
comp["power_module_hub"] = add_component("power_module_hub", "node",
|
||
"GHC-03_0")
|
||
comp["power_storage_rack"] = add_component("power_storage_rack",
|
||
"equipment", "GHC-03_1")
|
||
comp["nuclear_reactor"] = add_component("nuclear_reactor", "equipment",
|
||
"GHC-03_2")
|
||
comp["isru_module"] = add_component("isru_module", "equipment",
|
||
"GHC-03_2")
|
||
comp["mining_module"] = add_component("mining_module", "equipment",
|
||
"GHC-03_2")
|
||
comp["ore_fuel_storage"] = add_component("ore_fuel_storage",
|
||
"equipment", "GHC-03_2")
|
||
comp["binglun_3"] = add_component("binglun_3", "vehicle", "BL-03_0",
|
||
metadata={"block": 2, "role": "fuel_transport"})
|
||
comp["fuel_storage_mod"] = add_component("fuel_storage_mod",
|
||
"equipment", "GHC-04_0")
|
||
comp["centrifuge_mod"] = add_component("centrifuge_mod", "equipment",
|
||
"GHC-04_1")
|
||
comp["habitat_1"] = add_component("habitat_1", "module", "GHC-05_1",
|
||
metadata={"capacity": 4, "sleepBags": 2})
|
||
comp["habitat_2"] = add_component("habitat_2", "module", "GHC-05_1",
|
||
metadata={"capacity": 4, "sleepBags": 2})
|
||
comp["greenhouse"] = add_component("greenhouse", "module", "GHC-05_1",
|
||
metadata={"foldingArms": 4})
|
||
comp["lab_module"] = add_component("lab_module", "module", "GHC-05_1",
|
||
metadata={"zones": 3})
|
||
comp["wugang_2"] = add_component("wugang_2", "vehicle", "GHC-05_0",
|
||
metadata={"block": 2, "type": "lunar_lander"})
|
||
|
||
print(f"Components: {len(comp)}")
|
||
|
||
# ============================================================
|
||
# PHASE 5: Component Versions
|
||
# ============================================================
|
||
def add_version(component_key, event_key, display_name, **kwargs):
|
||
cid = comp[component_key]
|
||
cur.execute("""
|
||
INSERT INTO component_versions
|
||
(id, component_id, display_name, summary, description,
|
||
length_m, width_m, height_m, diameter_m, mass_t,
|
||
detail_url, properties, valid_from, started_by_event_id)
|
||
VALUES (gen_random_uuid(), %(cid)s, %(name)s, %(sum)s, %(desc)s,
|
||
%(len)s, %(wid)s, %(hei)s, %(dia)s, %(mass)s,
|
||
%(url)s, %(props)s,
|
||
(SELECT effective_at FROM mission_events WHERE id = %(ev)s),
|
||
%(ev)s)
|
||
ON CONFLICT DO NOTHING
|
||
""", {
|
||
"cid": cid, "name": display_name,
|
||
"sum": kwargs.get("summary"), "desc": kwargs.get("description"),
|
||
"len": kwargs.get("length_m"), "wid": kwargs.get("width_m"),
|
||
"hei": kwargs.get("height_m"), "dia": kwargs.get("diameter_m"),
|
||
"mass": kwargs.get("mass_t"), "url": kwargs.get("detail_url"),
|
||
"props": json.dumps(kwargs.get("properties")) if kwargs.get("properties") else None,
|
||
"ev": events[event_key],
|
||
})
|
||
|
||
add_version("core_cabin", "GHC-01_0", "广寒核心舱",
|
||
summary="广寒基地核心中枢,四向安装节点",
|
||
description="核心舱本体干重28.2吨,搭载2.5吨维生资源。配备4个标准安装节点和50kWh蓄电池组。",
|
||
mass_t=28.2, detail_url="/home/mission/Guanghan_Program/GHC-01")
|
||
add_version("binglun_1", "BL-01_0", "冰轮一号",
|
||
summary="首艘冰轮着陆器,Block 1,GHC-04后ISRU已关闭,转为专职燃料运输",
|
||
detail_url="/home/Spacecraft/Binglun_Lander")
|
||
add_version("binglun_2", "BL-02_0", "冰轮二号",
|
||
summary="第二艘冰轮着陆器,Block 1,专职燃料运输",
|
||
detail_url="/home/Spacecraft/Binglun_Lander")
|
||
add_version("power_module_hub", "GHC-03_0", "电力模块安装节点",
|
||
summary="十字型四向安装节点,电力模块中枢",
|
||
description="电力模块是独立十字结构,中心为四向安装节点。北部连接存储支架和加压走道模块,南部连接核反应堆,东部连接核燃料存储模块和离心机模块,西部连接ISRU、采矿模块和矿石/燃料存储模块。四个方向顶部各安装一组大型折叠散热面板。")
|
||
add_version("power_storage_rack", "GHC-03_1", "电力模块存储支架")
|
||
add_version("nuclear_reactor", "GHC-03_2", "核反应堆",
|
||
summary="广寒基地主电力来源,GHC-05后以30%功率运行",
|
||
properties={"powerPercent": 30})
|
||
add_version("isru_module", "GHC-03_2", "ISRU 模块",
|
||
summary="基地级原位资源利用设备,负责氢氧燃料生产")
|
||
add_version("mining_module", "GHC-03_2", "采矿模块",
|
||
summary="月面矿石采集设备,含采矿车和传送系统")
|
||
add_version("ore_fuel_storage", "GHC-03_2", "矿石/燃料存储模块",
|
||
summary="矿石原料和成品氢氧燃料的存储设施")
|
||
add_version("binglun_3", "BL-03_0", "冰轮三号",
|
||
summary="首艘Block 2冰轮着陆器,加宽燃料罐,接口与Block 1完全兼容",
|
||
detail_url="/home/Spacecraft/Binglun_Lander")
|
||
add_version("fuel_storage_mod", "GHC-04_0", "核燃料存储模块",
|
||
summary="核反应堆燃料组件存储及废料暂存")
|
||
add_version("centrifuge_mod", "GHC-04_1", "离心机模块",
|
||
summary="科学实验离心机,安装于电力模块顶部")
|
||
add_version("habitat_1", "GHC-05_4", "居住舱段一号",
|
||
summary="核心舱三号位(南侧),4铺位+2睡袋,远端连接电力模块",
|
||
description="运输构型高2.7m、长6.2m、宽5.0m(12.2吨)。展开后高3.2m、长6.2m、宽7.6m,含4个折叠铺位和2个睡袋挂点。",
|
||
length_m=6.2, width_m=7.6, height_m=3.2, mass_t=12.2,
|
||
properties={"capacity": 4, "sleepBags": 2,
|
||
"transportHeightM": 2.7, "transportLengthM": 6.2,
|
||
"transportWidthM": 5.0})
|
||
add_version("habitat_2", "GHC-05_5", "居住舱段二号",
|
||
summary="核心舱一号位(北侧),4铺位+2睡袋",
|
||
description="运输构型与居住舱段一号相同。展开后高3.2m、长6.2m、宽7.6m。展开过程中西侧折叠臂曾出现短暂卡滞,手动辅助释放后正常。",
|
||
length_m=6.2, width_m=7.6, height_m=3.2, mass_t=12.2,
|
||
properties={"capacity": 4, "sleepBags": 2})
|
||
add_version("greenhouse", "GHC-05_3", "温室舱段",
|
||
summary="核心舱四号位(西侧),4组折叠臂展开的透明面板,远端连接吴刚二号",
|
||
description="运输构型高2.8m、长8.7m、宽5.0m(13.5吨)。手动展开折叠框架后达到工作构型高3.2m、长8.7m、宽7.4m。配备自动灌溉系统和温度传感器。",
|
||
length_m=8.7, width_m=7.4, height_m=3.2, mass_t=13.5,
|
||
properties={"foldingArms": 4,
|
||
"transportHeightM": 2.8, "transportLengthM": 8.7,
|
||
"transportWidthM": 5.0})
|
||
add_version("lab_module", "GHC-05_6", "实验舱段",
|
||
summary="核心舱二号位(东侧),3个可调温区,四个舱段中质量最大",
|
||
description="运输构型高2.7m、长7.5m、宽5.0m(14.2吨)。展开后高3.2m、长7.5m、宽7.5m。含生物培养、材料科学、地质分析三个独立温区。",
|
||
length_m=7.5, width_m=7.5, height_m=3.2, mass_t=14.2,
|
||
properties={"zones": 3, "zoneNames": ["生物培养", "材料科学", "地质分析"],
|
||
"transportHeightM": 2.7, "transportLengthM": 7.5,
|
||
"transportWidthM": 5.0})
|
||
add_version("wugang_2", "GHC-05_0", "吴刚二号",
|
||
summary="首艘Block 2吴刚月面着陆器,GHC-05乘组搭乘抵达,高度雷达故障后手动着陆",
|
||
detail_url="/home/Spacecraft/Wugang_Lunar_Lander",
|
||
properties={"block": 2, "landingMode": "manual"})
|
||
|
||
print("Versions created")
|
||
|
||
# ============================================================
|
||
# PHASE 6: Ports
|
||
# ============================================================
|
||
def add_port(component_key, port_key, display_name, direction=None,
|
||
interface_type="structural"):
|
||
cur.execute("""
|
||
INSERT INTO ports (id, component_id, port_key, display_name,
|
||
direction, interface_type)
|
||
VALUES (gen_random_uuid(), %(cid)s, %(pkey)s, %(dname)s,
|
||
%(dir)s, %(iface)s)
|
||
ON CONFLICT (component_id, port_key) DO NOTHING
|
||
""", {
|
||
"cid": comp[component_key], "pkey": port_key,
|
||
"dname": display_name, "dir": direction, "iface": interface_type,
|
||
})
|
||
|
||
# Core cabin: 4 docking nodes
|
||
for d, name in [("north", "一号位(北)"), ("east", "二号位(东)"),
|
||
("south", "三号位(南)"), ("west", "四号位(西)")]:
|
||
add_port("core_cabin", d, name, d)
|
||
|
||
# Power module hub: 4 directional nodes
|
||
for d in ["north", "east", "south", "west"]:
|
||
add_port("power_module_hub", d, f"{'北东南西'['north east south west'.split().index(d)]}部安装口", d)
|
||
|
||
# Power sub-equipment
|
||
for key in ["power_storage_rack", "nuclear_reactor", "isru_module",
|
||
"mining_module", "ore_fuel_storage", "fuel_storage_mod",
|
||
"centrifuge_mod"]:
|
||
add_port(key, "mount", "安装接口")
|
||
|
||
# Habitat modules: core-side + distal
|
||
add_port("habitat_1", "core", "核心端接口", "north")
|
||
add_port("habitat_1", "distal", "远端对接口", "south")
|
||
add_port("habitat_2", "core", "核心端接口", "south")
|
||
|
||
# Greenhouse: core-side + distal
|
||
add_port("greenhouse", "core", "核心端接口", "east")
|
||
add_port("greenhouse", "distal", "远端对接口", "west")
|
||
|
||
# Lab: core-side only
|
||
add_port("lab_module", "core", "核心端接口", "west")
|
||
|
||
# Wugang #2
|
||
add_port("wugang_2", "dock", "对接口", interface_type="docking")
|
||
|
||
# Bingluns: fuel and power ports
|
||
for bl in ["binglun_1", "binglun_2", "binglun_3"]:
|
||
add_port(bl, "fuel_port", "燃料接口", interface_type="fuel")
|
||
add_port(bl, "power_port", "供电接口", interface_type="power")
|
||
|
||
print("Ports created")
|
||
|
||
# ============================================================
|
||
# PHASE 7: Connections
|
||
# ============================================================
|
||
def add_connection(comp_a, port_a, comp_b, port_b, conn_type,
|
||
event_key, valid_to_event=None):
|
||
cur.execute(
|
||
"SELECT id FROM ports WHERE component_id = %(cid)s AND port_key = %(pkey)s",
|
||
{"cid": comp[comp_a], "pkey": port_a})
|
||
pa = cur.fetchone()
|
||
cur.execute(
|
||
"SELECT id FROM ports WHERE component_id = %(cid)s AND port_key = %(pkey)s",
|
||
{"cid": comp[comp_b], "pkey": port_b})
|
||
pb = cur.fetchone()
|
||
if not pa or not pb:
|
||
print(f" WARN: port not found for {comp_a}.{port_a} <-> {comp_b}.{port_b}")
|
||
return
|
||
|
||
cur.execute(
|
||
"SELECT effective_at FROM mission_events WHERE id = %(ev)s",
|
||
{"ev": events[event_key]})
|
||
valid_from = cur.fetchone()["effective_at"]
|
||
|
||
valid_to = None
|
||
ended_by_id = None
|
||
if valid_to_event:
|
||
cur.execute(
|
||
"SELECT effective_at, id FROM mission_events WHERE id = %(ev)s",
|
||
{"ev": events[valid_to_event]})
|
||
row = cur.fetchone()
|
||
if row:
|
||
valid_to = row["effective_at"]
|
||
ended_by_id = row["id"]
|
||
|
||
cur.execute("""
|
||
INSERT INTO topology_connections
|
||
(id, base_id, port_a_id, port_b_id, connection_type,
|
||
valid_from, valid_to, established_by_event_id,
|
||
ended_by_event_id)
|
||
VALUES (gen_random_uuid(), %(base)s, %(pa)s, %(pb)s, %(ct)s,
|
||
%(vf)s, %(vt)s, %(ev)s, %(end_ev)s)
|
||
ON CONFLICT DO NOTHING
|
||
""", {
|
||
"base": base_id, "pa": pa["id"], "pb": pb["id"],
|
||
"ct": conn_type, "vf": valid_from, "vt": valid_to,
|
||
"ev": events[event_key], "end_ev": ended_by_id,
|
||
})
|
||
|
||
# GHC-02: Binglun #1 <-> #2 historical fuel connection
|
||
add_connection("binglun_1", "fuel_port", "binglun_2", "fuel_port",
|
||
"fuel", "GHC-02_0", valid_to_event="GHC-04_2")
|
||
|
||
# GHC-03: Core <-> Power (historical, removed in GHC-05)
|
||
add_connection("core_cabin", "south", "power_module_hub", "north",
|
||
"structural_mount", "GHC-03_3",
|
||
valid_to_event="GHC-05_2")
|
||
|
||
# GHC-03: Power sub-module connections
|
||
add_connection("power_module_hub", "north", "power_storage_rack",
|
||
"mount", "structural_mount", "GHC-03_1")
|
||
add_connection("power_module_hub", "south", "nuclear_reactor",
|
||
"mount", "structural_mount", "GHC-03_2")
|
||
add_connection("power_module_hub", "west", "isru_module",
|
||
"mount", "structural_mount", "GHC-03_2")
|
||
add_connection("power_module_hub", "west", "mining_module",
|
||
"mount", "structural_mount", "GHC-03_2")
|
||
add_connection("power_module_hub", "west", "ore_fuel_storage",
|
||
"mount", "structural_mount", "GHC-03_2")
|
||
|
||
# GHC-04: Power east-side equipment
|
||
add_connection("power_module_hub", "east", "fuel_storage_mod",
|
||
"mount", "structural_mount", "GHC-04_0")
|
||
add_connection("power_module_hub", "east", "centrifuge_mod",
|
||
"mount", "structural_mount", "GHC-04_1")
|
||
|
||
# GHC-04: Binglun fuel & power network
|
||
bl_events = {"binglun_1": "GHC-04_4", "binglun_2": "GHC-04_5",
|
||
"binglun_3": "GHC-04_6"}
|
||
hub_ports = {"binglun_1": "west", "binglun_2": "south",
|
||
"binglun_3": "east"}
|
||
for bl, ev in bl_events.items():
|
||
hub_port = hub_ports[bl]
|
||
add_connection(bl, "fuel_port", "power_module_hub", hub_port,
|
||
"fuel", ev)
|
||
add_connection(bl, "power_port", "power_module_hub", hub_port,
|
||
"power", ev)
|
||
|
||
# GHC-05: Core <-> four new modules (structural)
|
||
add_connection("core_cabin", "north", "habitat_2", "core",
|
||
"structural_mount", "GHC-05_5")
|
||
add_connection("core_cabin", "east", "lab_module", "core",
|
||
"structural_mount", "GHC-05_6")
|
||
add_connection("core_cabin", "south", "habitat_1", "core",
|
||
"structural_mount", "GHC-05_4")
|
||
add_connection("core_cabin", "west", "greenhouse", "core",
|
||
"structural_mount", "GHC-05_3")
|
||
|
||
# GHC-05: Pressurized passages
|
||
add_connection("greenhouse", "distal", "wugang_2", "dock",
|
||
"pressurized_passage", "GHC-05_7")
|
||
add_connection("habitat_1", "distal", "power_module_hub", "north",
|
||
"pressurized_passage", "GHC-05_4")
|
||
|
||
print("Connections created")
|
||
|
||
# ============================================================
|
||
# PHASE 8: Component States
|
||
# ============================================================
|
||
def add_state(component_key, state_kind, state_value, event_key,
|
||
details=None):
|
||
cur.execute("""
|
||
INSERT INTO component_states
|
||
(id, component_id, state_kind, state_value, details,
|
||
valid_from, started_by_event_id)
|
||
VALUES (gen_random_uuid(), %(cid)s, %(kind)s, %(val)s,
|
||
%(det)s,
|
||
(SELECT effective_at FROM mission_events WHERE id = %(ev)s),
|
||
%(ev)s)
|
||
ON CONFLICT DO NOTHING
|
||
""", {"cid": comp[component_key], "kind": state_kind,
|
||
"val": state_value,
|
||
"det": json.dumps(details) if details else None,
|
||
"ev": events[event_key]})
|
||
|
||
# Lifecycle: installed for all components
|
||
lifecycle_pairs = [
|
||
("core_cabin", "GHC-01_0"), ("binglun_1", "BL-01_0"),
|
||
("binglun_2", "BL-02_0"), ("power_module_hub", "GHC-03_0"),
|
||
("power_storage_rack", "GHC-03_1"), ("nuclear_reactor", "GHC-03_2"),
|
||
("isru_module", "GHC-03_2"), ("mining_module", "GHC-03_2"),
|
||
("ore_fuel_storage", "GHC-03_2"), ("binglun_3", "BL-03_0"),
|
||
("fuel_storage_mod", "GHC-04_0"), ("centrifuge_mod", "GHC-04_1"),
|
||
("habitat_1", "GHC-05_1"), ("habitat_2", "GHC-05_1"),
|
||
("greenhouse", "GHC-05_1"), ("lab_module", "GHC-05_1"),
|
||
("wugang_2", "GHC-05_0"),
|
||
]
|
||
for ck, ev in lifecycle_pairs:
|
||
add_state(ck, "lifecycle", "installed", ev)
|
||
|
||
# Operation: operational
|
||
ops_pairs = [
|
||
("core_cabin", "GHC-01_0"), ("binglun_1", "BL-01_0"),
|
||
("binglun_2", "BL-02_0"), ("binglun_3", "BL-03_0"),
|
||
("isru_module", "GHC-03_2"), ("mining_module", "GHC-03_2"),
|
||
("wugang_2", "GHC-05_0"),
|
||
]
|
||
for ck, ev in ops_pairs:
|
||
add_state(ck, "operation", "operational", ev)
|
||
|
||
# Nuclear reactor states: 15% (GHC-03) -> 100% (GHC-04) -> 30% (GHC-05)
|
||
add_state("nuclear_reactor", "operation", "operational", "GHC-03_4",
|
||
details={"powerPercent": 15})
|
||
# Close 15% at GHC-04 full power
|
||
cur.execute("""
|
||
UPDATE component_states
|
||
SET valid_to = (SELECT effective_at FROM mission_events WHERE id = %(ev)s),
|
||
ended_by_event_id = %(ev)s
|
||
WHERE component_id = %(cid)s
|
||
AND state_kind = 'operation'
|
||
AND details @> '{\"powerPercent\": 15}'
|
||
AND valid_to IS NULL
|
||
""", {"ev": events["GHC-04_3"], "cid": comp["nuclear_reactor"]})
|
||
# Insert 100%
|
||
add_state("nuclear_reactor", "operation", "operational", "GHC-04_3",
|
||
details={"powerPercent": 100})
|
||
# Close 100% at GHC-05 power adjustment
|
||
cur.execute("""
|
||
UPDATE component_states
|
||
SET valid_to = (SELECT effective_at FROM mission_events WHERE id = %(ev)s),
|
||
ended_by_event_id = %(ev)s
|
||
WHERE component_id = %(cid)s
|
||
AND state_kind = 'operation'
|
||
AND details @> '{\"powerPercent\": 100}'
|
||
AND valid_to IS NULL
|
||
""", {"ev": events["GHC-05_8"], "cid": comp["nuclear_reactor"]})
|
||
# Insert 30% (current)
|
||
add_state("nuclear_reactor", "operation", "operational", "GHC-05_8",
|
||
details={"powerPercent": 30})
|
||
|
||
print("States created")
|
||
print("\nSeed complete!")
|
||
print(f" Base: 1")
|
||
print(f" Missions: {len(mission_ids)}")
|
||
print(f" Events: {len(events)}")
|
||
print(f" Components: {len(comp)}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
seed()
|